mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 14:01:24 +08:00
Compare commits
63 Commits
codex/pr-8
...
v2026.5.5-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
013a2c50f6 | ||
|
|
6896bd3ddf | ||
|
|
9cb0b97f74 | ||
|
|
e820821950 | ||
|
|
ecf2dc58e1 | ||
|
|
817b56f22d | ||
|
|
258e153705 | ||
|
|
acdf0e432a | ||
|
|
3c04d7e710 | ||
|
|
1205c9ef1f | ||
|
|
ba5bc48f70 | ||
|
|
cbbdaf92a4 | ||
|
|
1692c84b8c | ||
|
|
0097427d08 | ||
|
|
2d2fc19e36 | ||
|
|
daff8916de | ||
|
|
3569edb38e | ||
|
|
9cc6cca75d | ||
|
|
e8ad813282 | ||
|
|
e8f0608b09 | ||
|
|
7470ea9073 | ||
|
|
ed4ed5aead | ||
|
|
3544ef0afa | ||
|
|
7da737c67d | ||
|
|
95e9e29219 | ||
|
|
31633bc0ec | ||
|
|
30927c8491 | ||
|
|
9a61edb419 | ||
|
|
e12dbf527f | ||
|
|
23319a3cc2 | ||
|
|
82e914e506 | ||
|
|
c82f66e3c2 | ||
|
|
191e821b71 | ||
|
|
7a2e7dba73 | ||
|
|
eda33431de | ||
|
|
4aa91b0b97 | ||
|
|
8a601b0607 | ||
|
|
6f9f36a38f | ||
|
|
c03449678e | ||
|
|
edbd3355be | ||
|
|
325df3efef | ||
|
|
2fc80754cf | ||
|
|
41f028e2ea | ||
|
|
303ff716d4 | ||
|
|
5fcdeae80c | ||
|
|
b73317c217 | ||
|
|
8f6bf65162 | ||
|
|
8017dc4c3b | ||
|
|
578d9072cf | ||
|
|
30b73bbf41 | ||
|
|
ade922ba98 | ||
|
|
997f8af734 | ||
|
|
6204a6fecc | ||
|
|
9f15c29397 | ||
|
|
cac973972c | ||
|
|
f8f18d53fc | ||
|
|
696f639cf6 | ||
|
|
079b937b46 | ||
|
|
32e36d355d | ||
|
|
12e1c67f22 | ||
|
|
766d02ff3b | ||
|
|
e9ebb6ce6c | ||
|
|
e0002c4b5b |
@@ -42,10 +42,12 @@ Use this skill for release and publish-time workflow. Keep ordinary development
|
||||
config footprint move, so do not blindly copy stale replacement annotations
|
||||
into release notes.
|
||||
- Do not delete or rewrite beta tags after their matching npm package has been
|
||||
published. If a pushed beta tag fails preflight before npm publish, delete and
|
||||
recreate the tag and prerelease at the fixed commit so npm prerelease versions
|
||||
stay contiguous. If a published beta needs a fix, commit the fix on the
|
||||
release branch and increment to the next `-beta.N`.
|
||||
published. If a pushed beta tag fails before npm publish, the version is not
|
||||
consumed: keep the same `-beta.N`, delete/recreate or force-move the git tag
|
||||
and prerelease to the fixed commit, and rerun preflight. Do not increment to
|
||||
the next beta number until the matching npm package has actually published.
|
||||
If a published beta needs a fix, commit the fix on the release branch and
|
||||
increment to the next `-beta.N`.
|
||||
- For a beta release train, run the fast local preflight first, publish the
|
||||
beta to npm `beta`, then run the expensive published-package roster focused
|
||||
on install/update/Docker/Parallels/NPM Telegram. If anything fails, fix it on
|
||||
|
||||
@@ -558,7 +558,7 @@ jobs:
|
||||
artifact_name: ${{ needs.prepare_release_package.outputs.artifact_name }}
|
||||
package_sha256: ${{ needs.prepare_release_package.outputs.package_sha256 }}
|
||||
suite_profile: custom
|
||||
docker_lanes: doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update
|
||||
docker_lanes: doctor-switch update-channel-switch update-corrupt-plugin upgrade-survivor published-upgrade-survivor plugins-offline plugin-update
|
||||
published_upgrade_survivor_baselines: ${{ needs.resolve_target.outputs.run_release_soak == 'true' && 'all-since-2026.4.23' || '' }}
|
||||
published_upgrade_survivor_scenarios: ${{ needs.resolve_target.outputs.run_release_soak == 'true' && 'reported-issues' || '' }}
|
||||
telegram_mode: mock-openai
|
||||
|
||||
92
.github/workflows/openclaw-release-publish.yml
vendored
92
.github/workflows/openclaw-release-publish.yml
vendored
@@ -33,7 +33,7 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
publish_openclaw_npm:
|
||||
description: Publish the OpenClaw npm package after plugin npm and ClawHub publish complete
|
||||
description: Publish the OpenClaw npm package after plugin npm succeeds; ClawHub may still run
|
||||
required: true
|
||||
default: true
|
||||
type: boolean
|
||||
@@ -169,15 +169,15 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
dispatch_and_wait() {
|
||||
dispatch_workflow() {
|
||||
local workflow="$1"
|
||||
shift
|
||||
|
||||
local before_json dispatch_output run_id status conclusion url
|
||||
local before_json dispatch_output run_id
|
||||
before_json="$(gh run list --repo "$GITHUB_REPOSITORY" --workflow "$workflow" --event workflow_dispatch --limit 100 --json databaseId --jq '[.[].databaseId]')"
|
||||
|
||||
dispatch_output="$(gh workflow run --repo "$GITHUB_REPOSITORY" "$workflow" --ref "$CHILD_WORKFLOW_REF" "$@" 2>&1)"
|
||||
printf '%s\n' "$dispatch_output"
|
||||
printf '%s\n' "$dispatch_output" >&2
|
||||
run_id="$(
|
||||
printf '%s\n' "$dispatch_output" |
|
||||
sed -nE 's#.*actions/runs/([0-9]+).*#\1#p' |
|
||||
@@ -202,15 +202,14 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Dispatched ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}"
|
||||
echo "Dispatched ${workflow}: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}" >&2
|
||||
printf '%s\n' "${run_id}"
|
||||
}
|
||||
|
||||
cancel_child() {
|
||||
if [[ -n "${run_id:-}" ]]; then
|
||||
echo "Cancelling child workflow ${workflow}: ${run_id}" >&2
|
||||
gh run cancel --repo "$GITHUB_REPOSITORY" "$run_id" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
trap cancel_child EXIT INT TERM
|
||||
wait_for_run() {
|
||||
local workflow="$1"
|
||||
local run_id="$2"
|
||||
local status conclusion url
|
||||
|
||||
while true; do
|
||||
status="$(gh run view --repo "$GITHUB_REPOSITORY" "$run_id" --json status --jq '.status')"
|
||||
@@ -219,7 +218,6 @@ jobs:
|
||||
fi
|
||||
sleep 30
|
||||
done
|
||||
trap - EXIT INT TERM
|
||||
|
||||
conclusion="$(gh run view --repo "$GITHUB_REPOSITORY" "$run_id" --json conclusion --jq '.conclusion')"
|
||||
url="$(gh run view --repo "$GITHUB_REPOSITORY" "$run_id" --json url --jq '.url')"
|
||||
@@ -229,16 +227,36 @@ jobs:
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
if [[ "$conclusion" != "success" ]]; then
|
||||
gh run view --repo "$GITHUB_REPOSITORY" "$run_id" --json jobs --jq '.jobs[] | select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url}' || true
|
||||
exit 1
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_run_background() {
|
||||
local workflow="$1"
|
||||
local run_id="$2"
|
||||
local result_file="$3"
|
||||
(
|
||||
if wait_for_run "${workflow}" "${run_id}"; then
|
||||
printf 'success\n' > "${result_file}"
|
||||
else
|
||||
printf 'failure\n' > "${result_file}"
|
||||
fi
|
||||
) &
|
||||
wait_run_pid="$!"
|
||||
}
|
||||
|
||||
{
|
||||
echo "### Publish sequence"
|
||||
echo
|
||||
echo "- Workflow ref: \`${CHILD_WORKFLOW_REF}\`"
|
||||
echo "- Release tag: \`${RELEASE_TAG}\`"
|
||||
echo "- Release SHA: \`${TARGET_SHA}\`"
|
||||
echo "- Plugin npm and ClawHub publish: dispatched in parallel"
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
echo "- OpenClaw npm publish: starts after plugin npm succeeds; ClawHub may still be running"
|
||||
else
|
||||
echo "- OpenClaw npm publish: skipped by input"
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
npm_args=(-f publish_scope="${PLUGIN_PUBLISH_SCOPE}" -f ref="${TARGET_SHA}")
|
||||
@@ -248,15 +266,53 @@ jobs:
|
||||
clawhub_args+=(-f plugins="${PLUGINS}")
|
||||
fi
|
||||
|
||||
dispatch_and_wait plugin-npm-release.yml "${npm_args[@]}"
|
||||
dispatch_and_wait plugin-clawhub-release.yml "${clawhub_args[@]}"
|
||||
plugin_npm_run_id="$(dispatch_workflow plugin-npm-release.yml "${npm_args[@]}")"
|
||||
plugin_clawhub_run_id="$(dispatch_workflow plugin-clawhub-release.yml "${clawhub_args[@]}")"
|
||||
|
||||
if ! wait_for_run plugin-npm-release.yml "${plugin_npm_run_id}"; then
|
||||
echo "Plugin npm publish failed; cancelling ClawHub publish child ${plugin_clawhub_run_id}." >&2
|
||||
gh run cancel --repo "$GITHUB_REPOSITORY" "${plugin_clawhub_run_id}" >/dev/null 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
openclaw_npm_run_id=""
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
dispatch_and_wait openclaw-npm-release.yml \
|
||||
openclaw_npm_run_id="$(dispatch_workflow openclaw-npm-release.yml \
|
||||
-f tag="${RELEASE_TAG}" \
|
||||
-f preflight_only=false \
|
||||
-f preflight_run_id="${PREFLIGHT_RUN_ID}" \
|
||||
-f npm_dist_tag="${RELEASE_NPM_DIST_TAG}"
|
||||
-f npm_dist_tag="${RELEASE_NPM_DIST_TAG}")"
|
||||
else
|
||||
echo "- OpenClaw npm publish: skipped by input" >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
|
||||
clawhub_result="$RUNNER_TEMP/clawhub-result.txt"
|
||||
wait_run_pid=""
|
||||
wait_for_run_background plugin-clawhub-release.yml "${plugin_clawhub_run_id}" "${clawhub_result}"
|
||||
clawhub_pid="${wait_run_pid}"
|
||||
|
||||
openclaw_result=""
|
||||
openclaw_pid=""
|
||||
if [[ -n "${openclaw_npm_run_id}" ]]; then
|
||||
openclaw_result="$RUNNER_TEMP/openclaw-npm-result.txt"
|
||||
wait_run_pid=""
|
||||
wait_for_run_background openclaw-npm-release.yml "${openclaw_npm_run_id}" "${openclaw_result}"
|
||||
openclaw_pid="${wait_run_pid}"
|
||||
fi
|
||||
|
||||
failed=0
|
||||
if ! wait "${clawhub_pid}"; then
|
||||
failed=1
|
||||
fi
|
||||
if [[ -n "${openclaw_pid}" ]] && ! wait "${openclaw_pid}"; then
|
||||
failed=1
|
||||
fi
|
||||
if [[ -f "${clawhub_result}" && "$(cat "${clawhub_result}")" != "success" ]]; then
|
||||
failed=1
|
||||
fi
|
||||
if [[ -n "${openclaw_result}" && -f "${openclaw_result}" && "$(cat "${openclaw_result}")" != "success" ]]; then
|
||||
failed=1
|
||||
fi
|
||||
if [[ "${failed}" != "0" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
4
.github/workflows/package-acceptance.yml
vendored
4
.github/workflows/package-acceptance.yml
vendored
@@ -386,10 +386,10 @@ jobs:
|
||||
docker_lanes="npm-onboard-channel-agent gateway-network config-reload"
|
||||
;;
|
||||
package)
|
||||
docker_lanes="npm-onboard-channel-agent doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update"
|
||||
docker_lanes="npm-onboard-channel-agent doctor-switch update-channel-switch update-corrupt-plugin upgrade-survivor published-upgrade-survivor plugins-offline plugin-update"
|
||||
;;
|
||||
product)
|
||||
docker_lanes="npm-onboard-channel-agent doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins plugin-update mcp-channels cron-mcp-cleanup openai-web-search-minimal openwebui"
|
||||
docker_lanes="npm-onboard-channel-agent doctor-switch update-channel-switch update-corrupt-plugin upgrade-survivor published-upgrade-survivor plugins plugin-update mcp-channels cron-mcp-cleanup openai-web-search-minimal openwebui"
|
||||
include_openwebui=true
|
||||
;;
|
||||
full)
|
||||
|
||||
4
.github/workflows/plugin-clawhub-release.yml
vendored
4
.github/workflows/plugin-clawhub-release.yml
vendored
@@ -182,7 +182,7 @@ jobs:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 6
|
||||
max-parallel: 12
|
||||
matrix:
|
||||
plugin: ${{ fromJson(needs.preview_plugins_clawhub.outputs.matrix) }}
|
||||
steps:
|
||||
@@ -263,7 +263,7 @@ jobs:
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 6
|
||||
max-parallel: 12
|
||||
matrix:
|
||||
plugin: ${{ fromJson(needs.preview_plugins_clawhub.outputs.matrix) }}
|
||||
steps:
|
||||
|
||||
51
CHANGELOG.md
51
CHANGELOG.md
@@ -2,7 +2,41 @@
|
||||
|
||||
Docs: https://docs.openclaw.ai
|
||||
|
||||
## Unreleased
|
||||
## 2026.5.5
|
||||
|
||||
### Fixes
|
||||
|
||||
- CLI/sessions: prune old unreferenced transcript, compaction checkpoint, and trajectory artifacts during normal `sessions cleanup`, so gateway restart or crash orphans do not accumulate indefinitely outside `sessions.json`. Fixes #77608. Thanks @slideshow-dingo.
|
||||
- Doctor/Codex: repair legacy `openai-codex/*` routes in primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel overrides, and stale session pins to canonical `openai/*`, selecting `agentRuntime.id: "codex"` only when the Codex plugin is installed, enabled, contributes the `codex` harness, and has usable OAuth; otherwise select `agentRuntime.id: "pi"`. Thanks @vincentkoc.
|
||||
- Plugins/update: keep installed official npm and ClawHub plugins such as Codex, Discord, WhatsApp, and diagnostics plugins synced during host updates even when disabled or previously exact-pinned, while preserving third-party plugin pins. Thanks @vincentkoc.
|
||||
- Video generation: accept provider-specific aspect-ratio and resolution hints at the tool boundary, normalize `720P` to MiniMax's supported `768P`, and stop sending Google `generateAudio` on Gemini video requests so provider fallback can recover from model-specific parameter differences. Thanks @vincentkoc.
|
||||
- Status: show compact Gateway process uptime and host system uptime in `/status`, making restart and host-lifetime checks visible from chat. Thanks @vincentkoc.
|
||||
- WhatsApp responsiveness: stop only verified stale local TUI clients when they degrade the Gateway event loop and delay replies. Thanks @vincentkoc.
|
||||
- Hooks/session-memory: run reset memory capture off the command reply path and make model-generated memory filename slugs opt-in with `llmSlug: true`, so `/new` and `/reset` no longer block WhatsApp and other message-channel reset replies on hook housekeeping or a nested model call. Thanks @vincentkoc.
|
||||
- CLI/gateway: pause non-TTY stdin after full CLI command completion and stop `openclaw agent` from falling back to embedded mode after gateway request/auth failures, so parent help commands exit cleanly and scoped delivery probes surface the real Gateway error immediately. Thanks @vincentkoc.
|
||||
- Gateway/model catalog: cache empty read-only model catalog results until reload, so TUI and control-plane refresh loops cannot hammer plugin metadata reads when no usable models are currently discovered. Thanks @vincentkoc.
|
||||
- Hooks/session-memory: add collision suffixes to fallback memory filenames so repeated `/new` or `/reset` captures in the same minute do not overwrite the earlier session archive. Thanks @vincentkoc.
|
||||
- TUI/sessions: bound the session picker to recent rows and use exact lookup-style refreshes for the active session, so dusty stores no longer make TUI hydrate weeks-old transcripts before becoming responsive. Thanks @vincentkoc.
|
||||
- Agents/context engines: keep hidden OpenClaw runtime-context custom messages out of context-engine assemble, afterTurn, and ingest hooks so transcript reconstruction plugins only see conversation messages. Thanks @vincentkoc.
|
||||
- TUI: skip the generic CLI respawn wrapper for interactive launches, exit cleanly on terminal loss, and refuse to restore heartbeat sessions as the remembered chat session, preventing stale heartbeat history and orphaned `openclaw-tui` processes on first boot. Thanks @vincentkoc.
|
||||
- Doctor/sessions: move heartbeat-poisoned default main session store entries to recovery keys and clear stale TUI restore pointers, so `doctor --fix` can repair instances already stuck on `agent:main:main` heartbeat history. Thanks @vincentkoc.
|
||||
- Gateway/shutdown: report structured shutdown warnings and HTTP close timeout warnings through `ShutdownResult` while preserving lifecycle hook hardening. Carries forward #41296. Thanks @edenfunf.
|
||||
- CLI/update: make dev-channel preflight lint opt-in and constrained when enabled, so `openclaw update --channel dev` no longer walks back otherwise-good main commits when Ubuntu hosts OOM-kill or fail parallel oxlint shards. Thanks @vincentkoc.
|
||||
- CLI/channels: skip config, proxy, channel-option catalog, banner-config, and plugin startup bootstrap for the bare `openclaw channels` parent-help command, so it exits promptly after printing help instead of loading configured channel plugins. Thanks @vincentkoc.
|
||||
- Gateway/shutdown: cancel delayed post-ready maintenance during close and suppress maintenance/cron startup after quick restarts, preventing orphaned background timers. Thanks @vincentkoc.
|
||||
- CLI/status: show the selected agent runtime/harness in `openclaw status` session rows so terminal status matches the `/status` runtime line. Thanks @vincentkoc.
|
||||
- Sessions CLI: show the selected agent runtime in the `openclaw sessions` table so terminal output matches the runtime visibility already present in JSON/status surfaces. Thanks @vincentkoc.
|
||||
- Control UI/sessions: show each session's agent runtime in the Sessions table and allow filtering by runtime labels, matching the Agents panel runtime wording. Thanks @vincentkoc.
|
||||
- Docker/Gateway: harden the gateway container by dropping `NET_RAW` and `NET_ADMIN` capabilities and enabling `no-new-privileges` in the bundled `docker-compose.yml`. Thanks @VintageAyu.
|
||||
- OpenAI/Gateway: flush the initial chat stream chunk correctly so first-token streaming is visible instead of being delayed behind later chunks.
|
||||
- Gateway/media: skip media sidecar handling for unrelated HTTP routes so non-media requests do not pay the media route behavior.
|
||||
- Discord: show reasoning text in progress drafts so streaming replies expose useful thinking/progress instead of blank draft updates.
|
||||
- Auth profiles: avoid putting providers on cooldown for format-level rejections, so fallback profiles can still be tried when a model name is unsupported.
|
||||
- Update/plugins: tolerate corrupt managed plugin records during update so core package updates can still complete and report the plugin repair path.
|
||||
- Update: stop dev-channel updates cleanly after a fetch failure instead of continuing into later update steps.
|
||||
- Agents/generated media: treat attachment-style message tool actions as completed chat sends, preventing duplicate fallback media posts when generated files were already uploaded.
|
||||
|
||||
## 2026.5.4
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -10,6 +44,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Changes
|
||||
|
||||
- Gateway/Windows: bind the default loopback gateway listener only to `127.0.0.1` on Windows so libuv's dual-stack `::1` behavior cannot wedge localhost HTTP requests. (#69701, fixes #69674) Thanks @SARAMALI15792.
|
||||
- Plugins/migration: emit catalog-backed install hints when `plugins.entries` or `plugins.allow` references an official external plugin that is not installed, so upgraded configs point operators to `openclaw plugins install <spec>` instead of telling them to remove valid plugin config. (#77483) Thanks @hclsys.
|
||||
- OpenAI/Codex media: advertise Codex audio transcription in runtime and manifest metadata and route active Codex chat models to the OpenAI transcription default instead of sending chat model ids to audio transcription. Thanks @vincentkoc.
|
||||
- Dependencies: refresh runtime and provider packages including Pi 0.73.0, ACPX adapters, OpenAI, Anthropic, Slack, and TypeScript native preview, while keeping the Bedrock runtime installer override pinned below the Windows ARM Node 24 npm resolver failure.
|
||||
@@ -59,22 +94,32 @@ Docs: https://docs.openclaw.ai
|
||||
- Plugins/ClawHub: annotate 429 errors from ClawHub with the reset window from `RateLimit-Reset`/`Retry-After` and append a `Sign in for higher rate limits.` hint when the request was unauthenticated, so users can see when downloads will recover and how to lift the cap. Thanks @romneyda.
|
||||
- Plugins/runtime state: add `registerIfAbsent` for atomic keyed-store dedupe claims that return whether a plugin successfully claimed a key without overwriting an existing live value. Thanks @amknight.
|
||||
- Plugin SDK: add plugin-owned `SessionEntry` slot projection and scoped trusted-policy session extension reads. (#75609; replaces part of #73384/#74483) Thanks @100yenadmin.
|
||||
- Sandbox/Windows: accept drive-absolute Docker bind sources while keeping sandbox blocked-path and allowed-root policy comparisons Windows-case-insensitive. (#42174) Thanks @6607changchun.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugins/install: honor the beta update channel for onboarding and doctor-managed plugin installs by requesting floating npm and ClawHub specs with `@beta` while keeping persistent install records on the catalog default. Thanks @vincentkoc.
|
||||
- WhatsApp/onboarding: canonicalize setup and pairing allowlist entries to WhatsApp's digit-only phone ids while still accepting E.164, JID, and `whatsapp:` inputs, so personal-phone allowlists match WhatsApp Web sender ids after setup. Thanks @vincentkoc.
|
||||
- Gateway/startup: load provider plugins that own explicitly configured image, video, or music generation defaults so generation tools become live after gateway restart instead of remaining catalog-only. Fixes #77244. Thanks @buyuangtampan, @Nikoxx99, and @vincentkoc.
|
||||
- Slack/subagents: keep resumed parent `message.send` calls in the originating Slack thread when ambient session thread context is present, and suppress successful silent child completion rows from follow-up findings. Thanks @bek91.
|
||||
- Slack/mentions: record thread participation for successful visible threaded Slack sends, including message-tool and media delivery paths, so unmentioned replies in bot-participated threads can bypass mention gating as documented. Fixes #77648. Thanks @bek91.
|
||||
- Infra/Windows: skip the POSIX `/tmp/openclaw` preferred path on Windows in `resolvePreferredOpenClawTmpDir` so log files, TTS temp files, and other writes land in `%TEMP%\openclaw-<uid>` instead of `C:\tmp\openclaw`. Fixes #60713. Thanks @juan-flores077.
|
||||
- Media/Windows: open saved attachment temp files read/write before fsync so Windows WebChat and `chat.send` media offloads no longer fail with EPERM during durability flush. (#76593) Thanks @qq230849622-a11y.
|
||||
- Agents/tools: honor narrow runtime tool allowlists when constructing embedded-runner tool families and bundled MCP/LSP runtimes, so cron/subagent runs that request tools such as `update_plan`, `browser`, `x_search`, channel login tools, or `group:plugins` no longer start with missing tools or unrelated bootstrap work. (#77519, #77532)
|
||||
- Codex plugin: mirror the experimental upstream app-server protocol and format generated TypeScript before drift checks, keeping OpenClaw's `experimentalApi` bridge compatible with latest Codex while preserving formatter gates.
|
||||
- Telegram/media: derive no-caption inbound media placeholders from saved MIME metadata instead of the Telegram `photo` shape, so non-image and mixed attachments no longer reach the model as `<media:image>`. Fixes #69793. Thanks @aspalagin.
|
||||
- Telegram/streaming: reuse the active preview as the first chunk for long text finals, so multi-chunk replies no longer create a transient extra bubble that appears and then disappears. Thanks @vincentkoc.
|
||||
- Agents/cache: keep per-turn runtime context out of ordinary chat system prompts while still delivering hidden current-turn context, restoring prompt-cache reuse on chat continuations. Fixes #77431. Thanks @Udjin79.
|
||||
- Gateway/startup: include resolved thinking and fast-mode defaults in the `agent model` startup log line, defaulting unset startup thinking to `medium` without mixing in reasoning visibility.
|
||||
- Gateway/update: resolve local gateway probe auth from the installed config during post-update restart verification, so token/device-authenticated VPS gateways are not misreported as unhealthy port conflicts after a package swap. Thanks @vincentkoc.
|
||||
- Agents/Tools: add post-compaction loop guard in `pi-embedded-runner` that arms after auto-compaction-retry and aborts the run with `compaction_loop_persisted` when the agent emits the same `(tool, args, result)` triple `windowSize` times (default 3) within that window. Disable via existing `tools.loopDetection.enabled`; tune via `tools.loopDetection.postCompactionGuard.windowSize`. Targets the failure mode where context-overflow + compaction does not break a tool-call loop. Refs #77474; carries forward #21597. Thanks @efpiva.
|
||||
- Gateway/watch: suppress sync-I/O trace output during `pnpm gateway:watch --benchmark` unless explicitly requested, so CPU profiling no longer floods the terminal with stack traces.
|
||||
- Gateway/watch: when benchmark sync-I/O tracing is explicitly enabled, tee trace blocks to the benchmark output log and filter them from the terminal pane while keeping normal Gateway logs visible.
|
||||
- Plugins/runtime-deps: include `json5` in the memory-core plugin runtime dependency set so packaged `memory_search` sandboxes can resolve generated OpenClaw runtime chunks that parse JSON5 config. Fixes #77461.
|
||||
- Plugins/Windows: show a Git install hint when npm plugin installation fails with `spawn git ENOENT`, and document the WhatsApp plugin's Git-on-PATH requirement for Baileys/libsignal installs.
|
||||
- Codex harness: preserve app-server usage-limit reset details and deliver OpenClaw-owned runtime failure notices through tool-only source-reply mode, so Telegram and other chat channels tell users when Codex subscription limits or API failures block a turn instead of going silent. (#77557) Thanks @pashpashpash.
|
||||
- Agents/OpenAI: default direct OpenAI Responses models to the SSE transport instead of WebSocket auto-selection, preventing pi runtime chat turns from hanging on servers where the WebSocket path stalls while the OpenAI HTTP stream works. Thanks @vincentkoc.
|
||||
- Plugins/update: repair missing plugin-local `openclaw` peer links before skipping unchanged npm plugin updates, so current external Codex installs can recover `openclaw/plugin-sdk/*` resolution during OTA repair. (#77544) Thanks @ProspectOre.
|
||||
- Discord/replies: treat failed final reply delivery as a failed turn instead of counting it as a delivered automatic visible reply, so guild/channel turns no longer show done when the final message was dropped. Fixes #77520. Thanks @Patrick-Erichsen.
|
||||
- Discord: prefer IPv4 for Discord REST and gateway WebSocket startup paths so IPv4-only networks no longer stall before Gateway READY and inbound message dispatch. Fixes #77398; refs #77526. Thanks @Beandon13.
|
||||
- Channels/plugins: key bundled package-state probes, env/config presence, and read-only command defaults by channel id instead of manifest plugin id, preserving setup and native-command detection for channel plugins whose package id differs from the channel alias. Thanks @vincentkoc.
|
||||
@@ -216,6 +261,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Google Meet: make Twilio setup status require an enabled `voice-call` plugin entry instead of treating a missing entry as ready. Thanks @vincentkoc.
|
||||
- Telegram: render shared interactive reply buttons in reply delivery so plugin approval messages show inline keyboards. (#76238) Thanks @keshavbotagent.
|
||||
- Cron/sessions: keep cron metadata rows without an on-disk transcript non-resumable until a transcript exists, so doctor and `sessions cleanup --fix-missing` no longer report or prune pre-transcript cron rows as broken sessions. Refs #77011.
|
||||
- OpenAI Codex: recreate missing bound app-server threads once when a stale `/codex bind` sidecar survives a restart, preserving the selected auth profile and turn overrides before retrying the inbound turn. (#76936) Thanks @keshavbotagent.
|
||||
- Agents/cli-runner: drop a saved `claude-cli` resume sessionId at preparation time when its on-disk transcript no longer exists in `~/.claude/projects/`, so a stale binding from a half-installed `update.run` cannot trap follow-up runs (auto-reply / Telegram direct) in a `claude --resume` timeout loop; the run starts fresh and the new sessionId is written back through the existing post-run flow. (#77030; refs #77011) Thanks @openperf.
|
||||
- Release validation: install the cross-OS TypeScript harness through Windows-safe Node/npm shims so native Windows package checks reach the OpenClaw smoke suites instead of exiting before artifact capture. Thanks @vincentkoc.
|
||||
- Release validation: let Windows packaged-upgrade checks continue after the shipped 2026.5.2 updater hits its native-module swap cleanup fallback, verifying the fallback-installed candidate through package metadata and downstream smoke instead of crashing on the immediate update-status probe. Thanks @vincentkoc.
|
||||
@@ -324,6 +370,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Update: repair doctor-migratable legacy config before persisting `openclaw update --channel ...`, so old Slack/Telegram streaming keys do not block switching to beta after a package update. Thanks @vincentkoc.
|
||||
- Web fetch: late-bind `web_fetch` config and provider fallback metadata from the active runtime snapshot, matching `web_search` so long-lived tools do not use stale fetch provider settings. Thanks @vincentkoc.
|
||||
- Plugins/discovery: demote the source-only TypeScript runtime check on already-installed `origin: "global"` plugin packages from a config-blocking error to a warning and let the runtime fall through to the TypeScript source via jiti, so a single broken installed package no longer blocks `plugins install` for unrelated plugins; install-time rejection of newly-installed source-only packages is unchanged. Thanks @romneyda.
|
||||
- Providers/OpenAI Codex: stop the OAuth progress spinner before showing the manual redirect paste prompt, so callback timeouts do not spam `Browser callback did not finish` across terminals.
|
||||
@@ -583,6 +630,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/reply context: label replied-to messages as the current user message target in model-visible metadata, so short replies are grounded to their explicit reply target instead of nearby chat history. (#76817) Thanks @obviyus.
|
||||
- Doctor/plugins: install configured missing official plugins such as Discord and Brave during doctor/update repair, auto-enable repaired provider plugins, preserve config when a download fails, and stop auto-enable from inventing plugin entries when no manifest declares a configured channel. Fixes #76872. Thanks @jack-stormentswe.
|
||||
- Codex/app-server: stabilize transcript mirror dedupe across re-mirrored turns so reordered snapshots no longer drop reasoning entries or duplicate the assistant reply. Refs #77012. (#77046) Thanks @openperf.
|
||||
- Agents/auth-profiles: do not record request-shape (`format`) rejections as auth-profile health failures, so a single per-session transcript-shape error (such as a prefill-strict 400 "conversation must end with a user message") no longer triggers a profile-wide cooldown that blocks every other healthy session sharing the same auth profile. Refs #77228. (#77280) Thanks @openperf.
|
||||
|
||||
## 2026.5.2
|
||||
|
||||
@@ -1396,6 +1444,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Gateway/plugins: enable the native `require()` fast path on Windows for bundled plugin modules so plugin loading uses `require()` instead of Jiti's transform pipeline, reducing startup from ~39s to ~2s on typical 6-plugin setups. Fixes #68656. (#74173) Thanks @galiniliev.
|
||||
- macOS app: detect stale Gateway TLS certificate pins, automatically repair trusted Tailscale Serve rotations, and surface paired-but-disconnected Mac companion nodes so partial Gateway connections no longer look healthy. Thanks @guti.
|
||||
- Feishu: recreate WebSocket clients with monitor-owned backoff only after SDK reconnect exhaustion, preserving heartbeat defaults and shutdown cleanup without treating recoverable SDK callback errors as terminal, so persistent connections recover without manual gateway restart. Fixes #52618; duplicate evidence #59753; related #55532, #68766, #72411, and #73739. Thanks @vincentkoc, @schumilin, @alex-xuweilong, @120106835, @sirfengyu, and @tianhaocui.
|
||||
- Agents/skills: require exact `<location>` skill paths for both single-skill and multi-skill prompt selection, so agents do not guess or hard-code skill file paths. (#74161) Thanks @lanzhi-lee.
|
||||
|
||||
## 2026.4.27
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ android {
|
||||
applicationId = "ai.openclaw.app"
|
||||
minSdk = 31
|
||||
targetSdk = 36
|
||||
versionCode = 2026050400
|
||||
versionName = "2026.5.4"
|
||||
versionCode = 2026050500
|
||||
versionName = "2026.5.5"
|
||||
ndk {
|
||||
// Support all major ABIs — native libs are tiny (~47 KB per ABI)
|
||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# OpenClaw iOS Changelog
|
||||
|
||||
## 2026.5.5 - 2026-05-05
|
||||
|
||||
Maintenance update for the current OpenClaw development release.
|
||||
|
||||
## 2026.5.4 - 2026-05-04
|
||||
|
||||
Maintenance update for the current OpenClaw development release.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Source of truth: apps/ios/version.json
|
||||
// Generated by scripts/ios-sync-versioning.ts.
|
||||
|
||||
OPENCLAW_IOS_VERSION = 2026.5.4
|
||||
OPENCLAW_MARKETING_VERSION = 2026.5.4
|
||||
OPENCLAW_IOS_VERSION = 2026.5.5
|
||||
OPENCLAW_MARKETING_VERSION = 2026.5.5
|
||||
OPENCLAW_BUILD_VERSION = 1
|
||||
|
||||
#include? "../build/Version.xcconfig"
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
Maintenance update for the current OpenClaw development release.
|
||||
|
||||
- Gateway pairing now supports scanning QR codes from Settings and accepts full copied setup-code messages while keeping non-loopback `ws://` setup links blocked.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2026.5.4"
|
||||
"version": "2026.5.5"
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2026.5.4</string>
|
||||
<string>2026.5.5</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2026050400</string>
|
||||
<string>2026050500</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>OpenClaw</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -49,6 +49,11 @@ services:
|
||||
# Let bundled local-model providers reach host-side LM Studio/Ollama via
|
||||
# http://host.docker.internal:<port>. Docker Desktop usually provides this
|
||||
# alias; the host-gateway mapping makes it work on Linux Docker Engine too.
|
||||
cap_drop:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
ports:
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
43c6f668cd8301f485c64e6a663dc1b19d38c146ce2572943e2dc961973e0c6f plugin-sdk-api-baseline.json
|
||||
1d877d94bebb634d90d929fe0581ba4bccf4d12d8342d179ae9bf1053e68c013 plugin-sdk-api-baseline.jsonl
|
||||
9cee7bd20801c7101d19a7912aa2c799b94de926ea9d2619d94770334889070e plugin-sdk-api-baseline.json
|
||||
a00d67f47382b5826711640bffebb18615ca54cc6cc5ab1b618ba57ee15e84f7 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -178,7 +178,7 @@ openclaw hooks enable <hook-name>
|
||||
|
||||
### session-memory details
|
||||
|
||||
Extracts the last 15 user/assistant messages, generates a descriptive filename slug via LLM, and saves to `<workspace>/memory/YYYY-MM-DD-slug.md` using the host local date. Requires `workspace.dir` to be configured.
|
||||
Extracts the last 15 user/assistant messages and saves to `<workspace>/memory/YYYY-MM-DD-HHMM.md` using the host local date. Memory capture runs in the background so `/new` and `/reset` acknowledgements are not delayed by transcript reads or optional slug generation. Set `hooks.internal.entries.session-memory.llmSlug: true` to generate descriptive filename slugs with the configured model. Requires `workspace.dir` to be configured.
|
||||
|
||||
<a id="bootstrap-extra-files"></a>
|
||||
|
||||
|
||||
@@ -344,6 +344,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
For text-only replies:
|
||||
|
||||
- short DM/group/topic previews: OpenClaw keeps the same preview message and performs a final edit in place, unless a visible non-preview message was sent after the preview appeared
|
||||
- long text finals that split into multiple Telegram messages reuse the existing preview as the first final chunk when possible, then send only the remaining chunks
|
||||
- previews followed by visible non-preview output: OpenClaw sends the completed reply as a fresh final message and cleans up the older preview, so the final answer appears after intermediate output
|
||||
- previews older than about one minute: OpenClaw sends the completed reply as a fresh final message and then cleans up the preview, so Telegram's visible timestamp reflects completion time instead of the preview creation time
|
||||
|
||||
|
||||
@@ -31,12 +31,13 @@ Healthy baseline:
|
||||
|
||||
### WhatsApp failure signatures
|
||||
|
||||
| Symptom | Fastest check | Fix |
|
||||
| ------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Connected but no DM replies | `openclaw pairing list whatsapp` | Approve sender or switch DM policy/allowlist. |
|
||||
| Group messages ignored | Check `requireMention` + mention patterns in config | Mention the bot or relax mention policy for that group. |
|
||||
| QR login times out with 408 | Check gateway `HTTPS_PROXY` / `HTTP_PROXY` env | Set a reachable proxy; use `NO_PROXY` only for bypasses. |
|
||||
| Random disconnect/relogin loops | `openclaw channels status --probe` + logs | Recent reconnects are flagged even when currently connected; watch logs, restart the gateway, then relink if flapping continues. |
|
||||
| Symptom | Fastest check | Fix |
|
||||
| ----------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Connected but no DM replies | `openclaw pairing list whatsapp` | Approve sender or switch DM policy/allowlist. |
|
||||
| Group messages ignored | Check `requireMention` + mention patterns in config | Mention the bot or relax mention policy for that group. |
|
||||
| QR login times out with 408 | Check gateway `HTTPS_PROXY` / `HTTP_PROXY` env | Set a reachable proxy; use `NO_PROXY` only for bypasses. |
|
||||
| Random disconnect/relogin loops | `openclaw channels status --probe` + logs | Recent reconnects are flagged even when currently connected; watch logs, restart the gateway, then relink if flapping continues. |
|
||||
| Replies arrive seconds/minutes late | `openclaw doctor --fix` | Doctor stops verified stale local TUI clients when they are degrading the Gateway event loop. |
|
||||
|
||||
Full troubleshooting: [WhatsApp troubleshooting](/channels/whatsapp#troubleshooting)
|
||||
|
||||
|
||||
@@ -26,6 +26,16 @@ openclaw plugins install @openclaw/whatsapp
|
||||
Use the bare package to follow the current official release tag. Pin an exact
|
||||
version only when you need a reproducible install.
|
||||
|
||||
On Windows, the WhatsApp plugin needs Git on `PATH` during npm install because
|
||||
one of its Baileys/libsignal dependencies is fetched from a git URL. Install
|
||||
Git for Windows, then restart the shell and rerun the install:
|
||||
|
||||
```powershell
|
||||
winget install --id Git.Git -e
|
||||
```
|
||||
|
||||
Portable Git also works if its `bin` directory is on `PATH`.
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Pairing" icon="link" href="/channels/pairing">
|
||||
Default DM policy is pairing for unknown senders.
|
||||
|
||||
@@ -45,6 +45,8 @@ Notes:
|
||||
- State integrity checks now detect orphan transcript files in the sessions directory. Archiving them as `.deleted.<timestamp>` requires an interactive confirmation; `--fix`, `--yes`, and headless runs leave them in place.
|
||||
- Doctor also scans `~/.openclaw/cron/jobs.json` (or `cron.store`) for legacy cron job shapes and can rewrite them in place before the scheduler has to auto-normalize them at runtime.
|
||||
- On Linux, doctor warns when the user's crontab still runs legacy `~/.openclaw/bin/ensure-whatsapp.sh`; that script is no longer maintained and can log false WhatsApp gateway outages when cron lacks the systemd user-bus environment.
|
||||
- When WhatsApp is enabled, doctor checks for a degraded Gateway event loop with local `openclaw-tui` clients still running. `doctor --fix` stops only verified local TUI clients so WhatsApp replies are not queued behind stale TUI refresh loops.
|
||||
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` selects `agentRuntime.id: "codex"` only when the Codex plugin is installed, enabled, contributes the `codex` harness, and has usable OAuth; otherwise it selects `agentRuntime.id: "pi"` so the route stays on the default OpenClaw runner.
|
||||
- Doctor cleans legacy plugin dependency staging state created by older OpenClaw versions. It also repairs missing downloadable plugins that are referenced by config, such as `plugins.entries`, configured channels, configured provider/search settings, or configured agent runtimes. During package updates, doctor skips package-manager plugin repair until the package swap is complete; rerun `openclaw doctor --fix` afterward if a configured plugin still needs recovery. If the download fails, doctor reports the install error and preserves the configured plugin entry for the next repair attempt.
|
||||
- Doctor repairs stale plugin config by removing missing plugin ids from `plugins.allow`/`plugins.entries`, plus matching dangling channel config, heartbeat targets, and channel model overrides when plugin discovery is healthy.
|
||||
- Doctor quarantines invalid plugin config by disabling the affected `plugins.entries.<id>` entry and removing its invalid `config` payload. Gateway startup already skips only that bad plugin so other plugins and channels can keep running.
|
||||
|
||||
@@ -282,7 +282,7 @@ Saves session context to memory when you issue `/new` or `/reset`.
|
||||
openclaw hooks enable session-memory
|
||||
```
|
||||
|
||||
**Output:** `~/.openclaw/workspace/memory/YYYY-MM-DD-slug.md`
|
||||
**Output:** `~/.openclaw/workspace/memory/YYYY-MM-DD-HHMM.md` by default. Set `hooks.internal.entries.session-memory.llmSlug: true` for model-generated filename slugs.
|
||||
|
||||
**See:** [session-memory documentation](/automation/hooks#session-memory)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ Notes:
|
||||
- Session status output separates `Execution:` from `Runtime:`. `Execution` is the sandbox path (`direct`, `docker/*`), while `Runtime` tells you whether the session is using `OpenClaw Pi Default`, `OpenAI Codex`, a CLI backend, or an ACP backend such as `codex (acp/acpx)`. See [Agent runtimes](/concepts/agent-runtimes) for the provider/model/runtime distinction.
|
||||
- MiniMax's raw `usage_percent` / `usagePercent` fields are remaining quota, so OpenClaw inverts them before display; count-based fields win when present. `model_remains` responses prefer the chat-model entry, derive the window label from timestamps when needed, and include the model name in the plan label.
|
||||
- When the current session snapshot is sparse, `/status` can backfill token and cache counters from the most recent transcript usage log. Existing nonzero live values still win over transcript fallback values.
|
||||
- `/status` includes compact Gateway process uptime and host system uptime.
|
||||
- Transcript fallback can also recover the active runtime model label when the live session entry is missing it. If that transcript model differs from the selected model, status resolves the context window against the recovered runtime model instead of the selected one.
|
||||
- For prompt-size accounting, transcript fallback prefers the larger prompt-oriented total when session metadata is missing or smaller, so custom-provider sessions do not collapse to `0` token displays.
|
||||
- Output includes per-agent session stores when multiple agents are configured.
|
||||
|
||||
@@ -38,8 +38,9 @@ openclaw --update
|
||||
- `--tag <dist-tag|version|spec>`: override the package target for this update only. For package installs, `main` maps to `github:openclaw/openclaw#main`.
|
||||
- `--dry-run`: preview planned update actions (channel/tag/target/restart flow) without writing config, installing, syncing plugins, or restarting.
|
||||
- `--json`: print machine-readable `UpdateRunResult` JSON, including
|
||||
`postUpdate.plugins.integrityDrifts` when npm plugin artifact drift is
|
||||
detected during post-update plugin sync.
|
||||
`postUpdate.plugins.warnings` when corrupt or unloadable managed plugins need
|
||||
repair after the core update succeeds, and `postUpdate.plugins.integrityDrifts`
|
||||
when npm plugin artifact drift is detected during post-update plugin sync.
|
||||
- `--timeout <seconds>`: per-step timeout (default is 1800s).
|
||||
- `--yes`: skip confirmation prompts (for example downgrade confirmation).
|
||||
|
||||
@@ -147,7 +148,7 @@ manually.
|
||||
Dev only.
|
||||
</Step>
|
||||
<Step title="Preflight build (dev only)">
|
||||
Runs lint and TypeScript build in a temp worktree. If the tip fails, walks back up to 10 commits to find the newest clean build.
|
||||
Runs the TypeScript build in a temp worktree. If the tip fails, walks back up to 10 commits to find the newest buildable commit. Set `OPENCLAW_UPDATE_PREFLIGHT_LINT=1` to also run lint during this preflight; lint runs in constrained serial mode because user update hosts are often smaller than CI runners.
|
||||
</Step>
|
||||
<Step title="Rebase">
|
||||
Rebases onto the selected commit (dev only).
|
||||
@@ -177,7 +178,7 @@ If an exact pinned npm plugin update resolves to an artifact whose integrity dif
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
Post-update plugin sync failures fail the update result and stop restart follow-up work. Fix the plugin install or update error, then rerun `openclaw update`.
|
||||
Post-update plugin sync failures that are scoped to a managed plugin are reported as warnings after the core update succeeds. The JSON result keeps the top-level update `status: "ok"` and reports `postUpdate.plugins.status: "warning"` with `openclaw doctor --fix` and `openclaw plugins inspect <id> --runtime --json` guidance. Unexpected updater or sync exceptions still fail the update result. Fix the plugin install or update error, then rerun `openclaw doctor --fix` or `openclaw update`.
|
||||
|
||||
When the updated Gateway starts, plugin loading is verify-only: startup does not run package managers or mutate dependency trees. Package-manager `update.run` restarts bypass the normal idle deferral and restart cooldown after the package tree has been swapped, so the old process cannot keep lazy-loading removed chunks.
|
||||
|
||||
|
||||
@@ -232,6 +232,8 @@ Scenarios (`extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime
|
||||
- `telegram-tools-compact-command`
|
||||
- `telegram-whoami-command`
|
||||
- `telegram-context-command`
|
||||
- `telegram-long-final-reuses-preview`
|
||||
- `telegram-long-final-three-chunks`
|
||||
|
||||
Output artifacts:
|
||||
|
||||
|
||||
@@ -107,6 +107,8 @@ cat ~/.openclaw/openclaw.json
|
||||
- Matrix channel legacy state migration (in `--fix` / `--repair` mode).
|
||||
- Gateway runtime checks (service installed but not running; cached launchd label).
|
||||
- Channel status warnings (probed from the running gateway).
|
||||
- WhatsApp responsiveness checks for degraded Gateway event-loop health with local TUI clients still running; `--fix` stops only verified local TUI clients.
|
||||
- Codex route repair for legacy `openai-codex/*` model refs in primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and session route pins; `--fix` rewrites them to `openai/*` and selects `agentRuntime.id: "codex"` only when the Codex plugin is installed, enabled, contributes the `codex` harness, and has usable OAuth. Otherwise it selects `agentRuntime.id: "pi"`.
|
||||
- Supervisor config audit (launchd/systemd/schtasks) with optional repair.
|
||||
- Embedded proxy environment cleanup for gateway services that captured shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` values during install or update.
|
||||
- Gateway runtime best-practice checks (Node vs Bun, version-manager paths).
|
||||
@@ -259,21 +261,22 @@ That stages grounded durable candidates into the short-term dreaming store while
|
||||
<Accordion title="2e. Codex OAuth provider overrides">
|
||||
If you previously added legacy OpenAI transport settings under `models.providers.openai-codex`, they can shadow the built-in Codex OAuth provider path that newer releases use automatically. Doctor warns when it sees those old transport settings alongside Codex OAuth so you can remove or rewrite the stale transport override and get the built-in routing/fallback behavior back. Custom proxies and header-only overrides are still supported and do not trigger this warning.
|
||||
</Accordion>
|
||||
<Accordion title="2f. Codex plugin route warnings">
|
||||
When the bundled Codex plugin is enabled, doctor also checks whether `openai-codex/*` primary model refs still resolve through the default PI runner. That combination is valid when you want Codex OAuth/subscription auth through PI, but it is easy to confuse with the native Codex app-server harness. Doctor warns and points to the explicit app-server shape: `openai/*` plus `agentRuntime.id: "codex"` or `OPENCLAW_AGENT_RUNTIME=codex`.
|
||||
<Accordion title="2f. Codex route repair">
|
||||
Doctor checks for legacy `openai-codex/*` model refs. Native Codex harness routing uses canonical `openai/*` model refs plus `agentRuntime.id: "codex"` so the turn goes through the Codex app-server harness instead of the OpenClaw PI OpenAI path.
|
||||
|
||||
Doctor does not repair this automatically because both routes are valid:
|
||||
In `--fix` / `--repair` mode, doctor rewrites affected default-agent and per-agent refs, including primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale persisted session route state:
|
||||
|
||||
- `openai-codex/*` + PI means "use Codex OAuth/subscription auth through the normal OpenClaw runner."
|
||||
- `openai/*` + `agentRuntime.id: "codex"` means "run the embedded turn through native Codex app-server."
|
||||
- `openai-codex/gpt-*` becomes `openai/gpt-*`.
|
||||
- The matching agent runtime becomes `agentRuntime.id: "codex"` only when Codex is installed, enabled, contributes the `codex` harness, and has usable OAuth.
|
||||
- Otherwise the matching agent runtime becomes `agentRuntime.id: "pi"`.
|
||||
- Existing model fallback lists are preserved with their legacy entries rewritten; copied per-model settings move from the legacy key to the canonical `openai/*` key.
|
||||
- Persisted session `modelProvider`/`providerOverride`, `model`/`modelOverride`, fallback notices, auth-profile pins, and Codex harness pins are repaired across all discovered agent session stores.
|
||||
- `/codex ...` means "control or bind a native Codex conversation from chat."
|
||||
- `/acp ...` or `runtime: "acp"` means "use the external ACP/acpx adapter."
|
||||
|
||||
If the warning appears, choose the route you intended and edit config manually. Keep the warning as-is when PI Codex OAuth is intentional.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2g. Session route cleanup">
|
||||
Doctor also scans the active sessions store for stale auto-created route state after you move the configured default/fallback model or runtime away from a plugin-owned route such as Codex.
|
||||
Doctor also scans discovered agent session stores for stale auto-created route state after you move configured models or runtime away from a plugin-owned route such as Codex.
|
||||
|
||||
`openclaw doctor --fix` can clear auto-created stale state such as `modelOverrideSource: "auto"` model pins, runtime model metadata, pinned harness ids, CLI session bindings, and auto auth-profile overrides when their owning route is no longer configured. Explicit user or legacy session model choices are reported for manual review and left untouched; switch them with `/model ...`, `/new`, or reset the session when that route is no longer intended.
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ targets the shipped npm package instead.
|
||||
Release checks call Package Acceptance with the package/update/plugin set:
|
||||
|
||||
```text
|
||||
doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update
|
||||
doctor-switch update-channel-switch update-corrupt-plugin upgrade-survivor published-upgrade-survivor plugins-offline plugin-update
|
||||
```
|
||||
|
||||
They also pass:
|
||||
@@ -178,9 +178,10 @@ published_upgrade_survivor_scenarios=reported-issues
|
||||
telegram_mode=mock-openai
|
||||
```
|
||||
|
||||
This keeps package migration, update channel switching, stale plugin dependency
|
||||
cleanup, offline plugin coverage, plugin update behavior, and Telegram package
|
||||
QA on the same resolved artifact.
|
||||
This keeps package migration, update channel switching, corrupt managed-plugin
|
||||
tolerance, stale plugin dependency cleanup, offline plugin coverage, plugin
|
||||
update behavior, and Telegram package QA on the same resolved artifact without
|
||||
making the default release package gate walk every published release.
|
||||
|
||||
`all-since-2026.4.23` is the Full Release CI upgrade sample: every stable npm-published release from `2026.4.23` through `latest`. For exhaustive published
|
||||
update migration coverage, use `all-since-2026.4.23` in the separate Update
|
||||
|
||||
@@ -332,7 +332,7 @@ See [ClawDock](/install/clawdock) for the full helper guide.
|
||||
`openclaw-cli` uses `network_mode: "service:openclaw-gateway"` so CLI
|
||||
commands can reach the gateway over `127.0.0.1`. Treat this as a shared
|
||||
trust boundary. The compose config drops `NET_RAW`/`NET_ADMIN` and enables
|
||||
`no-new-privileges` on `openclaw-cli`.
|
||||
`no-new-privileges` on both `openclaw-gateway` and `openclaw-cli`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Permissions and EACCES">
|
||||
|
||||
@@ -87,9 +87,10 @@ If your config uses `plugins.allow`, include `codex` there too:
|
||||
}
|
||||
```
|
||||
|
||||
Do not use `openai-codex/gpt-*` when you mean native Codex runtime. That prefix
|
||||
is the explicit "Codex OAuth through PI" route. Config changes apply to new or
|
||||
reset sessions; existing sessions keep their recorded runtime.
|
||||
Do not use `openai-codex/gpt-*` in config. That prefix is a legacy route that
|
||||
`openclaw doctor --fix` rewrites to `openai/gpt-*` across primary models,
|
||||
fallbacks, heartbeat/subagent/compaction overrides, hooks, channel overrides,
|
||||
and stale persisted session route pins.
|
||||
|
||||
## What this plugin changes
|
||||
|
||||
@@ -106,7 +107,9 @@ The bundled `codex` plugin contributes several separate capabilities:
|
||||
Enabling the plugin makes those capabilities available. It does **not**:
|
||||
|
||||
- start using Codex for every OpenAI model
|
||||
- convert `openai-codex/*` model refs into the native runtime
|
||||
- convert `openai-codex/*` model refs into the native runtime without doctor
|
||||
verifying that Codex is installed, enabled, contributes the `codex` harness,
|
||||
and is OAuth-ready
|
||||
- make ACP/acpx the default Codex path
|
||||
- hot-switch existing sessions that already recorded a PI runtime
|
||||
- replace OpenClaw channel delivery, session files, auth-profile storage, or
|
||||
@@ -145,10 +148,10 @@ want native app-server execution. Legacy `codex/*` model refs still auto-select
|
||||
the harness for compatibility, but runtime-backed legacy provider prefixes are
|
||||
not shown as normal model/provider choices.
|
||||
|
||||
If the `codex` plugin is enabled but the primary model is still
|
||||
`openai-codex/*`, `openclaw doctor` warns instead of changing the route. That is
|
||||
intentional: `openai-codex/*` remains the PI Codex OAuth/subscription path, and
|
||||
native app-server execution stays an explicit runtime choice.
|
||||
If any configured model route is still `openai-codex/*`, `openclaw doctor --fix`
|
||||
rewrites it to `openai/*`. For matching agent routes, it sets the agent runtime
|
||||
to `codex` only when the Codex plugin is installed, enabled, contributes the
|
||||
`codex` harness, and has usable OAuth; otherwise it sets the runtime to `pi`.
|
||||
|
||||
## Route map
|
||||
|
||||
@@ -158,15 +161,18 @@ Use this table before changing config:
|
||||
| ---------------------------------------------------- | -------------------------- | -------------------------------------- | ---------------------------- | ------------------------------ |
|
||||
| ChatGPT/Codex subscription with native Codex runtime | `openai/gpt-*` | `agentRuntime.id: "codex"` | Codex OAuth or Codex account | `Runtime: OpenAI Codex` |
|
||||
| OpenAI API through normal OpenClaw runner | `openai/gpt-*` | omitted or `runtime: "pi"` | OpenAI API key | `Runtime: OpenClaw Pi Default` |
|
||||
| ChatGPT/Codex subscription through PI | `openai-codex/gpt-*` | omitted or `runtime: "pi"` | OpenAI Codex OAuth provider | `Runtime: OpenClaw Pi Default` |
|
||||
| Legacy config that needs doctor repair | `openai-codex/gpt-*` | repaired to `codex` or `pi` | Existing configured auth | Recheck after `doctor --fix` |
|
||||
| Mixed providers with conservative auto mode | provider-specific refs | `agentRuntime.id: "auto"` | Per selected provider | Depends on selected runtime |
|
||||
| Explicit Codex ACP adapter session | ACP prompt/model dependent | `sessions_spawn` with `runtime: "acp"` | ACP backend auth | ACP task/session status |
|
||||
|
||||
The important split is provider versus runtime:
|
||||
|
||||
- `openai-codex/*` answers "which provider/auth route should PI use?"
|
||||
- `agentRuntime.id: "codex"` answers "which loop should execute this
|
||||
embedded turn?"
|
||||
- `openai-codex/*` is a legacy route that doctor rewrites.
|
||||
- `agentRuntime.id: "codex"` requires the Codex harness and fails closed if it
|
||||
is unavailable.
|
||||
- `agentRuntime.id: "auto"` lets registered harnesses claim matching provider
|
||||
routes, but canonical OpenAI refs are still PI-owned unless a harness supports
|
||||
that provider/model pair.
|
||||
- `/codex ...` answers "which native Codex conversation should this chat bind
|
||||
or control?"
|
||||
- ACP answers "which external harness process should acpx launch?"
|
||||
@@ -175,33 +181,30 @@ The important split is provider versus runtime:
|
||||
|
||||
OpenAI-family routes are prefix-specific. For the common subscription plus
|
||||
native Codex runtime setup, use `openai/*` with `agentRuntime.id: "codex"`.
|
||||
Use `openai-codex/*` only when you intentionally want Codex OAuth through PI:
|
||||
Treat `openai-codex/*` as legacy config that doctor should rewrite:
|
||||
|
||||
| Model ref | Runtime path | Use when |
|
||||
| --------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| `openai/gpt-5.4` | OpenAI provider through OpenClaw/PI plumbing | You want current direct OpenAI Platform API access with `OPENAI_API_KEY`. |
|
||||
| `openai-codex/gpt-5.5` | OpenAI Codex OAuth through OpenClaw/PI | You want ChatGPT/Codex subscription auth with the default PI runner. |
|
||||
| `openai-codex/gpt-5.5` | Legacy route repaired by doctor | You are on old config; run `openclaw doctor --fix` to rewrite it. |
|
||||
| `openai/gpt-5.5` + `agentRuntime.id: "codex"` | Codex app-server harness | You want ChatGPT/Codex subscription auth with native Codex execution. |
|
||||
|
||||
GPT-5.5 can appear on both direct OpenAI API-key and Codex subscription routes
|
||||
when your account exposes them. Use `openai/gpt-5.5` with the Codex app-server
|
||||
harness for native Codex runtime, `openai-codex/gpt-5.5` for PI OAuth, or
|
||||
`openai/gpt-5.5` without a Codex runtime override for direct API-key traffic.
|
||||
harness for native Codex runtime, or `openai/gpt-5.5` without a Codex runtime
|
||||
override for direct API-key traffic.
|
||||
|
||||
Legacy `codex/gpt-*` refs remain accepted as compatibility aliases. Doctor
|
||||
compatibility migration rewrites legacy primary runtime refs to canonical model
|
||||
refs and records the runtime policy separately, while fallback-only legacy refs
|
||||
are left unchanged because runtime is configured for the whole agent container.
|
||||
New PI Codex OAuth configs should use `openai-codex/gpt-*`; new native
|
||||
app-server harness configs should use `openai/gpt-*` plus
|
||||
`agentRuntime.id: "codex"`.
|
||||
compatibility migration rewrites legacy runtime refs to canonical model refs
|
||||
and records the runtime policy separately. New native app-server harness configs
|
||||
should use `openai/gpt-*` plus `agentRuntime.id: "codex"`.
|
||||
|
||||
`agents.defaults.imageModel` follows the same prefix split. Use
|
||||
`openai-codex/gpt-*` when image understanding should run through the OpenAI
|
||||
Codex OAuth provider path. Use `codex/gpt-*` when image understanding should run
|
||||
through a bounded Codex app-server turn. The Codex app-server model must
|
||||
advertise image input support; text-only Codex models fail before the media turn
|
||||
starts.
|
||||
`openai/gpt-*` for the normal OpenAI route and `codex/gpt-*` when image
|
||||
understanding should run through a bounded Codex app-server turn. Do not use
|
||||
`openai-codex/gpt-*`; doctor rewrites that legacy prefix to `openai/gpt-*`. The
|
||||
Codex app-server model must advertise image input support; text-only Codex
|
||||
models fail before the media turn starts.
|
||||
|
||||
Use `/status` to confirm the effective harness for the current session. If the
|
||||
selection is surprising, enable debug logging for the `agents/harness` subsystem
|
||||
@@ -211,22 +214,20 @@ in `auto` mode, each plugin candidate's support result.
|
||||
|
||||
### What doctor warnings mean
|
||||
|
||||
`openclaw doctor` warns when all of these are true:
|
||||
`openclaw doctor` warns when configured model refs or persisted session route
|
||||
state still use `openai-codex/*`. `openclaw doctor --fix` rewrites those routes
|
||||
to:
|
||||
|
||||
- the bundled `codex` plugin is enabled or allowed
|
||||
- an agent's primary model is `openai-codex/*`
|
||||
- that agent's effective runtime is not `codex`
|
||||
- `openai/<model>`
|
||||
- `agentRuntime.id: "codex"` when Codex is installed, enabled, contributes the
|
||||
`codex` harness, and has usable OAuth
|
||||
- `agentRuntime.id: "pi"` otherwise
|
||||
|
||||
That warning exists because users often expect "Codex plugin enabled" to imply
|
||||
"native Codex app-server runtime." OpenClaw does not make that leap. The warning
|
||||
means:
|
||||
|
||||
- **No change is required** if you intended ChatGPT/Codex OAuth through PI.
|
||||
- Change the model to `openai/<model>` and set
|
||||
`agentRuntime.id: "codex"` if you intended native app-server
|
||||
execution.
|
||||
- Existing sessions still need `/new` or `/reset` after a runtime change,
|
||||
because session runtime pins are sticky.
|
||||
The `codex` route forces the native Codex harness. The `pi` route keeps the
|
||||
agent on the default OpenClaw runner instead of enabling or installing Codex as
|
||||
a side effect of legacy-route cleanup.
|
||||
Doctor also repairs stale persisted session pins across discovered agent session
|
||||
stores so old conversations do not stay wedged on the removed route.
|
||||
|
||||
Harness selection is not a live session control. When an embedded turn runs,
|
||||
OpenClaw records the selected harness id on that session and keeps using it for
|
||||
@@ -349,7 +350,7 @@ Agents should route user requests by intent, not by the word "Codex" alone:
|
||||
| "File a support report for a bad Codex run" | `/diagnostics [note]` |
|
||||
| "Only send Codex feedback for this attached thread" | `/codex diagnostics [note]` |
|
||||
| "Use my ChatGPT/Codex subscription with Codex runtime" | `openai/*` plus `agentRuntime.id: "codex"` |
|
||||
| "Use my ChatGPT/Codex subscription through PI" | `openai-codex/*` model refs |
|
||||
| "Repair old `openai-codex/*` config/session pins" | `openclaw doctor --fix` |
|
||||
| "Run Codex through ACP/acpx" | ACP `sessions_spawn({ runtime: "acp", ... })` |
|
||||
| "Start Claude Code/Gemini/OpenCode/Cursor in a thread" | ACP/acpx, not `/codex` and not native sub-agents |
|
||||
|
||||
|
||||
@@ -18,6 +18,16 @@ Adds the WhatsApp channel surface for sending and receiving OpenClaw messages.
|
||||
|
||||
channels: whatsapp
|
||||
|
||||
## Windows install note
|
||||
|
||||
On Windows, the WhatsApp plugin needs Git on `PATH` during npm install because one of its Baileys/libsignal dependencies is fetched from a git URL. Install Git for Windows, then restart the shell and rerun the install:
|
||||
|
||||
```powershell
|
||||
winget install --id Git.Git -e
|
||||
```
|
||||
|
||||
Portable Git also works if its `bin` directory is on `PATH`.
|
||||
|
||||
## Related docs
|
||||
|
||||
- [whatsapp](/channels/whatsapp)
|
||||
|
||||
@@ -77,10 +77,13 @@ the maintainer-only release runbook.
|
||||
prior evidence stale.
|
||||
9. For beta, tag `vYYYY.M.D-beta.N`, then run `OpenClaw Release Publish` from
|
||||
the matching `release/YYYY.M.D` branch. It verifies `pnpm plugins:sync:check`,
|
||||
publishes all publishable plugin packages to npm first, publishes the same
|
||||
set to ClawHub second as ClawPack npm-pack tarballs, and then promotes the
|
||||
prepared OpenClaw npm preflight artifact with the matching dist-tag. After
|
||||
publish, run post-publish package
|
||||
dispatches all publishable plugin packages to npm and the same set to
|
||||
ClawHub in parallel, and then promotes the prepared OpenClaw npm preflight
|
||||
artifact with the matching dist-tag as soon as plugin npm publish succeeds.
|
||||
ClawHub publishing may still be running while OpenClaw npm publishes, but the
|
||||
release publish workflow does not finish until both plugin publish paths and
|
||||
the OpenClaw npm publish path have completed successfully. After publish, run
|
||||
the post-publish package
|
||||
acceptance against the published `openclaw@YYYY.M.D-beta.N` or
|
||||
`openclaw@beta` package. If a pushed or published prerelease needs a fix,
|
||||
cut the next matching prerelease number; do not delete or rewrite the old
|
||||
|
||||
@@ -152,7 +152,7 @@ Current source-of-truth:
|
||||
- `/help` shows the short help summary.
|
||||
- `/commands` shows the generated command catalog.
|
||||
- `/tools [compact|verbose]` shows what the current agent can use right now.
|
||||
- `/status` shows execution/runtime status, including `Execution`/`Runtime` labels and provider usage/quota when available.
|
||||
- `/status` shows execution/runtime status, Gateway and system uptime, plus provider usage/quota when available.
|
||||
- `/diagnostics [note]` is the owner-only support-report flow for Gateway bugs and Codex harness runs. It asks for explicit exec approval every time before running `openclaw gateway diagnostics export --json`; do not approve diagnostics with an allow-all rule. After approval, it sends a pasteable report with the local bundle path, manifest summary, privacy notes, and relevant session ids. In group chats, the approval prompt and report go to the owner privately. When the active session uses the OpenAI Codex harness, the same approval also sends relevant Codex feedback to OpenAI servers and the completed reply lists the OpenClaw session ids, Codex thread ids, and `codex resume <thread-id>` commands. See [Diagnostics Export](/gateway/diagnostics).
|
||||
- `/crestodian <request>` runs the Crestodian setup and repair helper from an owner DM.
|
||||
- `/tasks` lists active/recent background tasks for the current session.
|
||||
|
||||
@@ -198,9 +198,9 @@ role or use `first_frame` for single-image image-to-video.
|
||||
### Style controls
|
||||
|
||||
<ParamField path="aspectRatio" type="string">
|
||||
`1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`, or `adaptive`.
|
||||
Aspect-ratio hint such as `1:1`, `16:9`, `9:16`, `adaptive`, or a provider-specific value. OpenClaw normalizes or ignores unsupported values per provider.
|
||||
</ParamField>
|
||||
<ParamField path="resolution" type="string">`480P`, `720P`, `768P`, or `1080P`.</ParamField>
|
||||
<ParamField path="resolution" type="string">Resolution hint such as `480P`, `720P`, `768P`, `1080P`, `4K`, or a provider-specific value. OpenClaw normalizes or ignores unsupported values per provider.</ParamField>
|
||||
<ParamField path="durationSeconds" type="number">
|
||||
Target duration in seconds (rounded to nearest provider-supported value).
|
||||
</ParamField>
|
||||
|
||||
@@ -82,7 +82,7 @@ Notes:
|
||||
|
||||
- Model picker: list available models and set the session override.
|
||||
- Agent picker: choose a different agent.
|
||||
- Session picker: shows only sessions for the current agent.
|
||||
- Session picker: shows up to 50 sessions for the current agent updated in the last 7 days. Use `/session <key>` to jump to an older known session.
|
||||
- Settings: toggle deliver, tool output expansion, and thinking visibility.
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw ACP runtime backend",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,10 +25,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4",
|
||||
"openclawVersion": "2026.5.5-beta.1",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/alibaba-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Alibaba Model Studio video provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Amazon Bedrock Mantle (OpenAI-compatible) provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Amazon Bedrock provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Anthropic Vertex provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Anthropic provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/arcee-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Arcee provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/azure-speech",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Azure Speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/bluebubbles",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw BlueBubbles channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -12,7 +12,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -53,10 +53,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/bonjour",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Bonjour/mDNS gateway discovery",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Brave plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -20,10 +20,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/browser-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw browser tool plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/byteplus-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw BytePlus provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cerebras-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Cerebras provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Chutes.ai provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cloudflare-ai-gateway-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Cloudflare AI Gateway provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Codex harness and model provider plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,10 +27,10 @@
|
||||
"minHostVersion": ">=2026.5.1-beta.1"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -48,7 +48,10 @@ describe("codex conversation binding", () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
agentRuntimeMocks.ensureAuthProfileStore.mockReturnValue({ version: 1, profiles: {} });
|
||||
agentRuntimeMocks.ensureAuthProfileStore.mockReturnValue({
|
||||
version: 1,
|
||||
profiles: {},
|
||||
});
|
||||
agentRuntimeMocks.resolveAuthProfileOrder.mockReturnValue([]);
|
||||
agentRuntimeMocks.resolveOpenClawAgentDir.mockReturnValue("/agent");
|
||||
agentRuntimeMocks.resolveProviderIdForAuth.mockImplementation((provider: string) => provider);
|
||||
@@ -56,7 +59,9 @@ describe("codex conversation binding", () => {
|
||||
|
||||
it("uses the default Codex auth profile and omits the public OpenAI provider for new binds", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const config = { auth: { order: { "openai-codex": ["openai-codex:default"] } } };
|
||||
const config = {
|
||||
auth: { order: { "openai-codex": ["openai-codex:default"] } },
|
||||
};
|
||||
const requests: Array<{ method: string; params: Record<string, unknown> }> = [];
|
||||
agentRuntimeMocks.ensureAuthProfileStore.mockReturnValue({
|
||||
version: 1,
|
||||
@@ -220,6 +225,142 @@ describe("codex conversation binding", () => {
|
||||
expect(result).toEqual({ handled: true });
|
||||
});
|
||||
|
||||
it("recreates a missing bound thread and preserves auth plus turn overrides", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
agentRuntimeMocks.ensureAuthProfileStore.mockReturnValue({
|
||||
version: 1,
|
||||
profiles: {
|
||||
work: {
|
||||
type: "oauth",
|
||||
provider: "openai-codex",
|
||||
access: "access-token",
|
||||
},
|
||||
},
|
||||
});
|
||||
await fs.writeFile(
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
JSON.stringify({
|
||||
schemaVersion: 1,
|
||||
threadId: "thread-old",
|
||||
cwd: tempDir,
|
||||
authProfileId: "work",
|
||||
model: "gpt-5.4-mini",
|
||||
modelProvider: "openai",
|
||||
approvalPolicy: "on-request",
|
||||
sandbox: "workspace-write",
|
||||
serviceTier: "fast",
|
||||
}),
|
||||
);
|
||||
const requests: Array<{ method: string; params: Record<string, unknown> }> = [];
|
||||
const notificationHandlers: Array<(notification: Record<string, unknown>) => void> = [];
|
||||
sharedClientMocks.getSharedCodexAppServerClient.mockResolvedValue({
|
||||
request: vi.fn(async (method: string, requestParams: Record<string, unknown>) => {
|
||||
requests.push({ method, params: requestParams });
|
||||
if (method === "turn/start" && requestParams.threadId === "thread-old") {
|
||||
throw new Error("thread not found: thread-old");
|
||||
}
|
||||
if (method === "thread/start") {
|
||||
return {
|
||||
thread: { id: "thread-new", cwd: tempDir },
|
||||
model: "gpt-5.4-mini",
|
||||
};
|
||||
}
|
||||
if (method === "turn/start" && requestParams.threadId === "thread-new") {
|
||||
setImmediate(() => {
|
||||
for (const handler of notificationHandlers) {
|
||||
handler({
|
||||
method: "turn/completed",
|
||||
params: {
|
||||
threadId: "thread-new",
|
||||
turn: {
|
||||
id: "turn-new",
|
||||
status: "completed",
|
||||
items: [
|
||||
{
|
||||
id: "assistant-1",
|
||||
type: "agentMessage",
|
||||
text: "Recovered",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
return { turn: { id: "turn-new" } };
|
||||
}
|
||||
throw new Error(`unexpected method: ${method}`);
|
||||
}),
|
||||
addNotificationHandler: vi.fn((handler) => {
|
||||
notificationHandlers.push(handler);
|
||||
return () => undefined;
|
||||
}),
|
||||
addRequestHandler: vi.fn(() => () => undefined),
|
||||
});
|
||||
|
||||
const result = await handleCodexConversationInboundClaim(
|
||||
{
|
||||
content: "hi again",
|
||||
bodyForAgent: "hi again",
|
||||
channel: "telegram",
|
||||
isGroup: false,
|
||||
commandAuthorized: true,
|
||||
},
|
||||
{
|
||||
channelId: "telegram",
|
||||
pluginBinding: {
|
||||
bindingId: "binding-1",
|
||||
pluginId: "codex",
|
||||
pluginRoot: tempDir,
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "5185575566",
|
||||
boundAt: Date.now(),
|
||||
data: {
|
||||
kind: "codex-app-server-session",
|
||||
version: 1,
|
||||
sessionFile,
|
||||
workspaceDir: tempDir,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ timeoutMs: 500 },
|
||||
);
|
||||
|
||||
expect(result).toEqual({ handled: true, reply: { text: "Recovered" } });
|
||||
expect(requests.map((request) => request.method)).toEqual([
|
||||
"turn/start",
|
||||
"thread/start",
|
||||
"turn/start",
|
||||
]);
|
||||
expect(sharedClientMocks.getSharedCodexAppServerClient).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ authProfileId: "work" }),
|
||||
);
|
||||
expect(requests[1]?.params).toMatchObject({
|
||||
model: "gpt-5.4-mini",
|
||||
approvalPolicy: "on-request",
|
||||
sandbox: "workspace-write",
|
||||
serviceTier: "fast",
|
||||
});
|
||||
expect(requests[1]?.params).not.toHaveProperty("modelProvider");
|
||||
expect(requests[2]?.params).toMatchObject({
|
||||
threadId: "thread-new",
|
||||
approvalPolicy: "on-request",
|
||||
serviceTier: "fast",
|
||||
});
|
||||
const savedBinding = JSON.parse(
|
||||
await fs.readFile(`${sessionFile}.codex-app-server.json`, "utf8"),
|
||||
);
|
||||
expect(savedBinding).toMatchObject({
|
||||
threadId: "thread-new",
|
||||
authProfileId: "work",
|
||||
approvalPolicy: "on-request",
|
||||
sandbox: "workspace-write",
|
||||
serviceTier: "fast",
|
||||
});
|
||||
expect(savedBinding).not.toHaveProperty("modelProvider");
|
||||
});
|
||||
|
||||
it("returns a clean failure reply when app-server turn start rejects", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
await fs.writeFile(
|
||||
|
||||
@@ -10,8 +10,11 @@ import { CODEX_CONTROL_METHODS } from "./app-server/capabilities.js";
|
||||
import {
|
||||
codexSandboxPolicyForTurn,
|
||||
resolveCodexAppServerRuntimeOptions,
|
||||
type CodexAppServerApprovalPolicy,
|
||||
type CodexAppServerSandboxMode,
|
||||
} from "./app-server/config.js";
|
||||
import {
|
||||
type CodexServiceTier,
|
||||
type CodexThreadResumeResponse,
|
||||
type CodexThreadStartResponse,
|
||||
type CodexTurnStartResponse,
|
||||
@@ -59,6 +62,9 @@ type CodexConversationStartParams = {
|
||||
model?: string;
|
||||
modelProvider?: string;
|
||||
authProfileId?: string;
|
||||
approvalPolicy?: CodexAppServerApprovalPolicy;
|
||||
sandbox?: CodexAppServerSandboxMode;
|
||||
serviceTier?: CodexServiceTier;
|
||||
};
|
||||
|
||||
type BoundTurnResult = {
|
||||
@@ -100,6 +106,9 @@ export async function startCodexConversationThread(
|
||||
model: params.model,
|
||||
modelProvider: params.modelProvider,
|
||||
authProfileId,
|
||||
approvalPolicy: params.approvalPolicy,
|
||||
sandbox: params.sandbox,
|
||||
serviceTier: params.serviceTier,
|
||||
config: params.config,
|
||||
});
|
||||
} else {
|
||||
@@ -110,6 +119,9 @@ export async function startCodexConversationThread(
|
||||
model: params.model,
|
||||
modelProvider: params.modelProvider,
|
||||
authProfileId,
|
||||
approvalPolicy: params.approvalPolicy,
|
||||
sandbox: params.sandbox,
|
||||
serviceTier: params.serviceTier,
|
||||
config: params.config,
|
||||
});
|
||||
}
|
||||
@@ -137,7 +149,7 @@ export async function handleCodexConversationInboundClaim(
|
||||
}
|
||||
try {
|
||||
const result = await enqueueBoundTurn(data.sessionFile, () =>
|
||||
runBoundTurn({
|
||||
runBoundTurnWithMissingThreadRecovery({
|
||||
data,
|
||||
prompt,
|
||||
event,
|
||||
@@ -177,9 +189,14 @@ async function attachExistingThread(params: {
|
||||
model?: string;
|
||||
modelProvider?: string;
|
||||
authProfileId?: string;
|
||||
approvalPolicy?: CodexAppServerApprovalPolicy;
|
||||
sandbox?: CodexAppServerSandboxMode;
|
||||
serviceTier?: CodexServiceTier;
|
||||
config?: CodexAppServerAuthProfileLookup["config"];
|
||||
}): Promise<void> {
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.pluginConfig });
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({
|
||||
pluginConfig: params.pluginConfig,
|
||||
});
|
||||
const modelProvider = resolveThreadRequestModelProvider({
|
||||
authProfileId: params.authProfileId,
|
||||
modelProvider: params.modelProvider,
|
||||
@@ -196,10 +213,12 @@ async function attachExistingThread(params: {
|
||||
threadId: params.threadId,
|
||||
...(params.model ? { model: params.model } : {}),
|
||||
...(modelProvider ? { modelProvider } : {}),
|
||||
approvalPolicy: runtime.approvalPolicy,
|
||||
approvalPolicy: params.approvalPolicy ?? runtime.approvalPolicy,
|
||||
approvalsReviewer: runtime.approvalsReviewer,
|
||||
sandbox: runtime.sandbox,
|
||||
...(runtime.serviceTier ? { serviceTier: runtime.serviceTier } : {}),
|
||||
sandbox: params.sandbox ?? runtime.sandbox,
|
||||
...((params.serviceTier ?? runtime.serviceTier)
|
||||
? { serviceTier: params.serviceTier ?? runtime.serviceTier }
|
||||
: {}),
|
||||
persistExtendedHistory: true,
|
||||
},
|
||||
{ timeoutMs: runtime.requestTimeoutMs },
|
||||
@@ -217,9 +236,9 @@ async function attachExistingThread(params: {
|
||||
authProfileId: params.authProfileId,
|
||||
modelProvider: response.modelProvider ?? params.modelProvider,
|
||||
}),
|
||||
approvalPolicy: runtime.approvalPolicy,
|
||||
sandbox: runtime.sandbox,
|
||||
serviceTier: runtime.serviceTier,
|
||||
approvalPolicy: params.approvalPolicy ?? runtime.approvalPolicy,
|
||||
sandbox: params.sandbox ?? runtime.sandbox,
|
||||
serviceTier: params.serviceTier ?? runtime.serviceTier,
|
||||
},
|
||||
{
|
||||
config: params.config,
|
||||
@@ -234,9 +253,14 @@ async function createThread(params: {
|
||||
model?: string;
|
||||
modelProvider?: string;
|
||||
authProfileId?: string;
|
||||
approvalPolicy?: CodexAppServerApprovalPolicy;
|
||||
sandbox?: CodexAppServerSandboxMode;
|
||||
serviceTier?: CodexServiceTier;
|
||||
config?: CodexAppServerAuthProfileLookup["config"];
|
||||
}): Promise<void> {
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.pluginConfig });
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({
|
||||
pluginConfig: params.pluginConfig,
|
||||
});
|
||||
const modelProvider = resolveThreadRequestModelProvider({
|
||||
authProfileId: params.authProfileId,
|
||||
modelProvider: params.modelProvider,
|
||||
@@ -253,10 +277,12 @@ async function createThread(params: {
|
||||
cwd: params.workspaceDir,
|
||||
...(params.model ? { model: params.model } : {}),
|
||||
...(modelProvider ? { modelProvider } : {}),
|
||||
approvalPolicy: runtime.approvalPolicy,
|
||||
approvalPolicy: params.approvalPolicy ?? runtime.approvalPolicy,
|
||||
approvalsReviewer: runtime.approvalsReviewer,
|
||||
sandbox: runtime.sandbox,
|
||||
...(runtime.serviceTier ? { serviceTier: runtime.serviceTier } : {}),
|
||||
sandbox: params.sandbox ?? runtime.sandbox,
|
||||
...((params.serviceTier ?? runtime.serviceTier)
|
||||
? { serviceTier: params.serviceTier ?? runtime.serviceTier }
|
||||
: {}),
|
||||
developerInstructions:
|
||||
"This Codex thread is bound to an OpenClaw conversation. Answer normally; OpenClaw will deliver your final response back to the conversation.",
|
||||
experimentalRawEvents: true,
|
||||
@@ -276,9 +302,9 @@ async function createThread(params: {
|
||||
authProfileId: params.authProfileId,
|
||||
modelProvider: response.modelProvider ?? params.modelProvider,
|
||||
}),
|
||||
approvalPolicy: runtime.approvalPolicy,
|
||||
sandbox: runtime.sandbox,
|
||||
serviceTier: runtime.serviceTier,
|
||||
approvalPolicy: params.approvalPolicy ?? runtime.approvalPolicy,
|
||||
sandbox: params.sandbox ?? runtime.sandbox,
|
||||
serviceTier: params.serviceTier ?? runtime.serviceTier,
|
||||
},
|
||||
{
|
||||
config: params.config,
|
||||
@@ -293,7 +319,9 @@ async function runBoundTurn(params: {
|
||||
pluginConfig?: unknown;
|
||||
timeoutMs?: number;
|
||||
}): Promise<BoundTurnResult> {
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.pluginConfig });
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({
|
||||
pluginConfig: params.pluginConfig,
|
||||
});
|
||||
const binding = await readCodexAppServerBinding(params.data.sessionFile);
|
||||
const threadId = binding?.threadId;
|
||||
if (!threadId) {
|
||||
@@ -350,7 +378,10 @@ async function runBoundTurn(params: {
|
||||
"turn/start",
|
||||
{
|
||||
threadId,
|
||||
input: buildCodexConversationTurnInput({ prompt: params.prompt, event: params.event }),
|
||||
input: buildCodexConversationTurnInput({
|
||||
prompt: params.prompt,
|
||||
event: params.event,
|
||||
}),
|
||||
cwd: binding.cwd || params.data.workspaceDir,
|
||||
approvalPolicy: binding.approvalPolicy ?? runtime.approvalPolicy,
|
||||
approvalsReviewer: runtime.approvalsReviewer,
|
||||
@@ -389,6 +420,39 @@ async function runBoundTurn(params: {
|
||||
}
|
||||
}
|
||||
|
||||
async function runBoundTurnWithMissingThreadRecovery(params: {
|
||||
data: CodexConversationBindingData;
|
||||
prompt: string;
|
||||
event: PluginHookInboundClaimEvent;
|
||||
pluginConfig?: unknown;
|
||||
timeoutMs?: number;
|
||||
}): Promise<BoundTurnResult> {
|
||||
try {
|
||||
return await runBoundTurn(params);
|
||||
} catch (error) {
|
||||
if (!isCodexThreadNotFoundError(error)) {
|
||||
throw error;
|
||||
}
|
||||
const binding = await readCodexAppServerBinding(params.data.sessionFile);
|
||||
await startCodexConversationThread({
|
||||
pluginConfig: params.pluginConfig,
|
||||
sessionFile: params.data.sessionFile,
|
||||
workspaceDir: binding?.cwd || params.data.workspaceDir,
|
||||
model: binding?.model,
|
||||
modelProvider: binding?.modelProvider,
|
||||
authProfileId: binding?.authProfileId,
|
||||
approvalPolicy: binding?.approvalPolicy,
|
||||
sandbox: binding?.sandbox,
|
||||
serviceTier: binding?.serviceTier,
|
||||
});
|
||||
return await runBoundTurn(params);
|
||||
}
|
||||
}
|
||||
|
||||
function isCodexThreadNotFoundError(error: unknown): boolean {
|
||||
return /\bthread not found:/iu.test(formatErrorMessage(error));
|
||||
}
|
||||
|
||||
function enqueueBoundTurn<T>(key: string, run: () => Promise<T>): Promise<T> {
|
||||
const state = getGlobalState();
|
||||
const previous = state.queues.get(key) ?? Promise.resolve();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/comfy-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw ComfyUI provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/copilot-proxy",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Copilot Proxy provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepgram-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Deepgram media-understanding provider",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepinfra-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw DeepInfra provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepseek-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw DeepSeek provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw diagnostics OpenTelemetry exporter",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,10 +34,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw diagnostics Prometheus exporter",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw diff viewer plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -30,10 +30,10 @@
|
||||
"minHostVersion": ">=2026.4.30"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4",
|
||||
"openclawVersion": "2026.5.5-beta.1",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./assets/viewer-runtime.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Discord channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,7 +21,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -65,10 +65,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -82,6 +82,8 @@ export function createDiscordDraftPreviewController(params: {
|
||||
});
|
||||
let previewToolProgressSuppressed = false;
|
||||
let previewToolProgressLines: string[] = [];
|
||||
let reasoningProgressRawText = "";
|
||||
let lastReasoningProgressLine: string | undefined;
|
||||
const progressSeed = `${params.accountId}:${params.deliverChannelId}`;
|
||||
|
||||
const renderProgressDraft = async (options?: { flush?: boolean }) => {
|
||||
@@ -116,6 +118,8 @@ export function createDiscordDraftPreviewController(params: {
|
||||
draftChunker?.reset();
|
||||
previewToolProgressSuppressed = false;
|
||||
previewToolProgressLines = [];
|
||||
reasoningProgressRawText = "";
|
||||
lastReasoningProgressLine = undefined;
|
||||
};
|
||||
|
||||
const forceNewMessageIfNeeded = () => {
|
||||
@@ -163,8 +167,11 @@ export function createDiscordDraftPreviewController(params: {
|
||||
return;
|
||||
}
|
||||
const normalized = line?.replace(/\s+/g, " ").trim();
|
||||
if (!normalized) {
|
||||
return;
|
||||
}
|
||||
if (discordStreamMode !== "progress") {
|
||||
if (!previewToolProgressEnabled || previewToolProgressSuppressed || !normalized) {
|
||||
if (!previewToolProgressEnabled || previewToolProgressSuppressed) {
|
||||
return;
|
||||
}
|
||||
const previous = previewToolProgressLines.at(-1);
|
||||
@@ -200,6 +207,36 @@ export function createDiscordDraftPreviewController(params: {
|
||||
await renderProgressDraft();
|
||||
}
|
||||
},
|
||||
async pushReasoningProgress(text?: string) {
|
||||
if (!draftStream || discordStreamMode !== "progress" || !text) {
|
||||
return;
|
||||
}
|
||||
reasoningProgressRawText = mergeReasoningProgressText(reasoningProgressRawText, text);
|
||||
const normalized = normalizeReasoningProgressLine(reasoningProgressRawText);
|
||||
if (!normalized) {
|
||||
return;
|
||||
}
|
||||
if (previewToolProgressEnabled && !previewToolProgressSuppressed) {
|
||||
const priorIndex =
|
||||
lastReasoningProgressLine === undefined
|
||||
? -1
|
||||
: previewToolProgressLines.lastIndexOf(lastReasoningProgressLine);
|
||||
if (priorIndex >= 0) {
|
||||
previewToolProgressLines = [...previewToolProgressLines];
|
||||
previewToolProgressLines[priorIndex] = normalized;
|
||||
} else {
|
||||
previewToolProgressLines = [...previewToolProgressLines, normalized].slice(
|
||||
-resolveChannelProgressDraftMaxLines(params.discordConfig),
|
||||
);
|
||||
}
|
||||
lastReasoningProgressLine = normalized;
|
||||
}
|
||||
const alreadyStarted = progressDraftGate.hasStarted;
|
||||
await progressDraftGate.noteWork();
|
||||
if (alreadyStarted && progressDraftGate.hasStarted) {
|
||||
await renderProgressDraft();
|
||||
}
|
||||
},
|
||||
resolvePreviewFinalText(text?: string) {
|
||||
if (typeof text !== "string") {
|
||||
return undefined;
|
||||
@@ -329,3 +366,29 @@ export function createDiscordDraftPreviewController(params: {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeReasoningProgressLine(text: string): string {
|
||||
return text
|
||||
.replace(/^\s*(?:>\s*)?Reasoning:\s*/i, "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
function mergeReasoningProgressText(current: string, incoming: string): string {
|
||||
if (!current) {
|
||||
return incoming;
|
||||
}
|
||||
const normalizedCurrent = normalizeReasoningProgressLine(current);
|
||||
const normalizedIncoming = normalizeReasoningProgressLine(incoming);
|
||||
if (!normalizedIncoming || normalizedIncoming === normalizedCurrent) {
|
||||
return current;
|
||||
}
|
||||
if (isReasoningSnapshotText(incoming) || normalizedIncoming.startsWith(normalizedCurrent)) {
|
||||
return incoming;
|
||||
}
|
||||
return `${current}${incoming}`;
|
||||
}
|
||||
|
||||
function isReasoningSnapshotText(text: string): boolean {
|
||||
return /^\s*(?:>\s*)?Reasoning:\s*/i.test(text);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ type DispatchInboundParams = {
|
||||
sendFinalReply: (payload: ReplyPayload) => boolean | Promise<boolean>;
|
||||
};
|
||||
replyOptions?: {
|
||||
onReasoningStream?: () => Promise<void> | void;
|
||||
onReasoningStream?: (payload?: { text?: string }) => Promise<void> | void;
|
||||
onReasoningEnd?: () => Promise<void> | void;
|
||||
onToolStart?: (payload: {
|
||||
name?: string;
|
||||
@@ -105,6 +105,7 @@ type DispatchInboundParams = {
|
||||
detailMode?: "explain" | "raw";
|
||||
}) => Promise<void> | void;
|
||||
onItemEvent?: (payload: {
|
||||
kind?: string;
|
||||
progressText?: string;
|
||||
summary?: string;
|
||||
title?: string;
|
||||
@@ -1616,6 +1617,72 @@ describe("processDiscordMessage draft streaming", () => {
|
||||
expect(draftStream.update).toHaveBeenCalledWith("Shelling\n🛠️ Exec\n• done");
|
||||
});
|
||||
|
||||
it("shows reasoning text instead of a bare Reasoning progress line", async () => {
|
||||
const draftStream = createMockDraftStreamForTest();
|
||||
|
||||
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
|
||||
await params?.replyOptions?.onToolStart?.({ name: "exec", phase: "start" });
|
||||
await params?.replyOptions?.onItemEvent?.({
|
||||
kind: "analysis",
|
||||
title: "Reasoning",
|
||||
});
|
||||
await params?.replyOptions?.onReasoningStream?.({ text: "Reading " });
|
||||
await params?.replyOptions?.onReasoningStream?.({ text: "the event projector" });
|
||||
return createNoQueuedDispatchResult();
|
||||
});
|
||||
|
||||
const ctx = await createAutomaticSourceDeliveryContext({
|
||||
discordConfig: {
|
||||
streaming: {
|
||||
mode: "progress",
|
||||
progress: {
|
||||
label: "Clawing...",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await runProcessDiscordMessage(ctx);
|
||||
|
||||
expect(draftStream.update).toHaveBeenCalledWith(
|
||||
"Clawing...\n🛠️ Exec\n• Reading the event projector",
|
||||
);
|
||||
expect(draftStream.update).not.toHaveBeenCalledWith(expect.stringContaining("Reasoning"));
|
||||
});
|
||||
|
||||
it("replaces reasoning snapshots instead of appending duplicates", async () => {
|
||||
const draftStream = createMockDraftStreamForTest();
|
||||
|
||||
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
|
||||
await params?.replyOptions?.onToolStart?.({ name: "exec", phase: "start" });
|
||||
await params?.replyOptions?.onReasoningStream?.({ text: "Reasoning:\n_Checking files_" });
|
||||
await params?.replyOptions?.onReasoningStream?.({
|
||||
text: "Reasoning:\n_Checking files and tests_",
|
||||
});
|
||||
return createNoQueuedDispatchResult();
|
||||
});
|
||||
|
||||
const ctx = await createAutomaticSourceDeliveryContext({
|
||||
discordConfig: {
|
||||
streaming: {
|
||||
mode: "progress",
|
||||
progress: {
|
||||
label: "Clawing...",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await runProcessDiscordMessage(ctx);
|
||||
|
||||
expect(draftStream.update).toHaveBeenCalledWith(
|
||||
"Clawing...\n🛠️ Exec\n• _Checking files and tests_",
|
||||
);
|
||||
expect(draftStream.update).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining("_Checking files_Reasoning:"),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps Discord progress lines across assistant boundaries", async () => {
|
||||
const draftStream = createMockDraftStreamForTest();
|
||||
|
||||
|
||||
@@ -660,8 +660,9 @@ export async function processDiscordMessage(
|
||||
onModelSelected,
|
||||
suppressDefaultToolProgressMessages:
|
||||
draftPreview.suppressDefaultToolProgressMessages ? true : undefined,
|
||||
onReasoningStream: async () => {
|
||||
onReasoningStream: async (payload) => {
|
||||
await statusReactions.setThinking();
|
||||
await draftPreview.pushReasoningProgress(payload?.text);
|
||||
},
|
||||
onToolStart: async (payload) => {
|
||||
if (isProcessAborted(abortSignal)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/document-extract-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw local document extraction plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/duckduckgo-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw DuckDuckGo plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/elevenlabs-speech",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw ElevenLabs speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/exa-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Exa plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fal-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw fal provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -47,10 +47,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/file-transfer",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw file transfer plugin (file_fetch, dir_list, dir_fetch, file_write)",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/firecrawl-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Firecrawl plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fireworks-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Fireworks provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/github-copilot-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw GitHub Copilot provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Google Meet participant plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -33,10 +33,10 @@
|
||||
"minHostVersion": ">=2026.4.20"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -88,7 +88,7 @@ export function createGoogleVideoGenerationProviderMetadata(): Omit<
|
||||
supportsAspectRatio: true,
|
||||
supportsResolution: true,
|
||||
supportsSize: true,
|
||||
supportsAudio: true,
|
||||
supportsAudio: false,
|
||||
},
|
||||
imageToVideo: {
|
||||
enabled: true,
|
||||
@@ -101,7 +101,7 @@ export function createGoogleVideoGenerationProviderMetadata(): Omit<
|
||||
supportsAspectRatio: true,
|
||||
supportsResolution: true,
|
||||
supportsSize: true,
|
||||
supportsAudio: true,
|
||||
supportsAudio: false,
|
||||
},
|
||||
videoToVideo: {
|
||||
enabled: true,
|
||||
@@ -114,7 +114,7 @@ export function createGoogleVideoGenerationProviderMetadata(): Omit<
|
||||
supportsAspectRatio: true,
|
||||
supportsResolution: true,
|
||||
supportsSize: true,
|
||||
supportsAudio: true,
|
||||
supportsAudio: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-plugin",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Google plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -86,11 +86,11 @@ describe("google video generation provider", () => {
|
||||
durationSeconds: 4,
|
||||
aspectRatio: "16:9",
|
||||
resolution: "720p",
|
||||
generateAudio: true,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(request?.config).not.toHaveProperty("numberOfVideos");
|
||||
expect(request?.config).not.toHaveProperty("generateAudio");
|
||||
expect(result.videos).toHaveLength(1);
|
||||
expect(result.videos[0]?.mimeType).toBe("video/mp4");
|
||||
expect(createGoogleGenAIMock).toHaveBeenCalledWith(
|
||||
|
||||
@@ -322,7 +322,6 @@ async function generateGoogleVideoViaRest(params: {
|
||||
durationSeconds?: number;
|
||||
aspectRatio?: "16:9" | "9:16";
|
||||
resolution?: "720p" | "1080p";
|
||||
audio?: boolean;
|
||||
}): Promise<unknown> {
|
||||
let operation = await requestGoogleVideoJson({
|
||||
url: `${params.baseUrl}/${resolveGoogleVideoRestModelPath(params.model)}:predictLongRunning`,
|
||||
@@ -337,7 +336,6 @@ async function generateGoogleVideoViaRest(params: {
|
||||
: {}),
|
||||
...(params.aspectRatio ? { aspectRatio: params.aspectRatio } : {}),
|
||||
...(params.resolution ? { resolution: params.resolution } : {}),
|
||||
...(params.audio === true ? { generateAudio: true } : {}),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -429,7 +427,6 @@ export function buildGoogleVideoGenerationProvider(): VideoGenerationProvider {
|
||||
...(typeof durationSeconds === "number" ? { durationSeconds } : {}),
|
||||
...(aspectRatio ? { aspectRatio } : {}),
|
||||
...(resolution ? { resolution } : {}),
|
||||
...(req.audio === true ? { generateAudio: true } : {}),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -446,7 +443,6 @@ export function buildGoogleVideoGenerationProvider(): VideoGenerationProvider {
|
||||
durationSeconds,
|
||||
aspectRatio,
|
||||
resolution,
|
||||
audio: req.audio,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -480,7 +476,6 @@ export function buildGoogleVideoGenerationProvider(): VideoGenerationProvider {
|
||||
durationSeconds,
|
||||
aspectRatio,
|
||||
resolution,
|
||||
audio: req.audio,
|
||||
});
|
||||
generatedVideos = extractGeneratedVideos(operation);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Google Chat channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -17,7 +17,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -75,10 +75,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/gradium-speech",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Gradium speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/groq-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Groq media-understanding provider",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/huggingface-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Hugging Face provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/image-generation-core",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw image generation runtime package",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/imessage",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw iMessage channel plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/inworld-speech",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Inworld speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/irc",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw IRC channel plugin",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kilocode-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Kilo Gateway provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kimi-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw Kimi provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw LINE channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -15,7 +15,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -45,10 +45,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/litellm-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw LiteLLM provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/llm-task",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw JSON-only LLM task plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/lmstudio-provider",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw LM Studio provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/lobster",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,10 +25,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 2026.5.5
|
||||
|
||||
### Changes
|
||||
|
||||
- Version alignment with core OpenClaw release numbers.
|
||||
|
||||
## 2026.5.4
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/matrix",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Matrix channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,7 +21,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/mattermost",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw Mattermost channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -15,7 +15,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/media-understanding-core",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw media understanding runtime package",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-core",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw core memory search plugin",
|
||||
"type": "module",
|
||||
@@ -14,7 +14,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-lancedb",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall/capture",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,10 +26,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.4"
|
||||
"pluginApi": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.4"
|
||||
"openclawVersion": "2026.5.5-beta.1"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-wiki",
|
||||
"version": "2026.5.4",
|
||||
"version": "2026.5.5-beta.1",
|
||||
"private": true,
|
||||
"description": "OpenClaw persistent wiki plugin",
|
||||
"type": "module",
|
||||
@@ -13,7 +13,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.5.4"
|
||||
"openclaw": ">=2026.5.5-beta.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user