Route normal [telegram][diag] polling diagnostics through runtime.log while keeping non-diag Telegram warnings/errors and offset persistence failures on runtime.error.
Verification:
- node scripts/run-vitest.mjs extensions/telegram/src/monitor.test.ts (34 passed)
- git diff --check
- CI run 26378692736 passed on 979c6f31a4Fixes#82957
Repair explicit anchorless iMessage watch payloads by GUID before debounce/routing, and drop unrecoverable payloads fail-closed instead of routing them as sender DMs.
Closes#84470.
Refs #84503.
Thanks @zhangguiping-xydt and @zqchris.
Fix Google Vertex production ADC mode support by routing explicit google-vertex models to the Vertex transport and relying on google-auth-library for request-time ADC resolution.
Verification:
- pnpm install --frozen-lockfile
- pnpm test extensions/google/transport-stream.test.ts extensions/google/index.test.ts src/config/zod-schema.models.test.ts src/agents/pi-embedded-runner/model.inline-provider.test.ts -- --reporter=verbose
- pnpm check:changed
- GitHub PR checks green on c4b7cad4df
- Live ADC smoke reached Google Vertex auth/transport and failed only because the configured redacted project has the Vertex AI API disabled
Co-authored-by: Damian Finol <damian@felixpago.com>
* fix: clean up browser MCP subprocess tree
* fix: clean up windows browser mcp tree before close
* fix(browser): repair chrome mcp cleanup rebase
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(compaction): preserve partial summary on mid-chain chunk failure
When summarizing multiple chunks, if a chunk fails after at least one
chunk has already succeeded, return the partial summary instead of
propagating the error and losing all summarization progress.
Abort and timeout errors still propagate immediately. First-chunk
failures still rethrow so the existing fallback path runs.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(compaction): use content array for assistant messages to match updated AgentMessage type
* fix(compaction): use as-unknown-as-AgentMessage cast for assistant test fixtures
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
maybeRecoverSuspiciousConfigRead unconditionally recorded
lastObservedSuspiciousSignature in health state even when
restoredFromBackup was false (copyFile failed). The guard at
resolveConfigReadRecoveryContext then prevented the same
signature from ever being retried, permanently accepting the
suspicious config on every subsequent launch.
Only record the dedup signature when the backup restore
actually succeeded.
* fix: avoid false telegram pairing prompts
* docs: add telegram pairing changelog
* refactor(telegram): share pairing-store gating and align isGroup check
Extract loadTelegramPairingStoreIfNeeded so the text-fragment flush path
and resolveTelegramGroupAllowFromContext share one implementation, and
align the isGroup derivation in the flush path with the
'group || supergroup' form used elsewhere in bot-handlers.runtime.ts.
Note on transient-vs-known errors: readChannelAllowFromStore already
translates missing-file (ENOENT) and JSON parse failures to an empty
allowlist internally, so the only errors that escape into the new
silent-drop path are unexpected I/O failures (EMFILE/EACCES/EIO/...) —
unpaired senders still get a pairing challenge as expected.
* fix(telegram): skip pairing-store read when commands.allowFrom already authorizes the sender
Native command auth resolves group/dm allow context (which may read the
pairing store) before checking commands.allowFrom. On DMs with
dmPolicy: "pairing", a transient pairing-store I/O failure was therefore
dropping commands from senders explicitly authorized by
commands.allowFrom.telegram.
Add a skipPairingStoreRead hint on resolveTelegramGroupAllowFromContext /
loadTelegramPairingStoreIfNeeded, precompute the command authorization
once at chat scope before the context call, and pass the hint when that
pre-check already authorizes the sender. The post-context command auth
check still owns the topic-scoped decision.
Regression covers a DM /status from a sender allowed by
commands.allowFrom.telegram with dmPolicy: "pairing" and a rejecting
readChannelAllowFromStore mock.
* fix(telegram): satisfy test-types on harness readChannelAllowFromStore
CI check-test-types failed because the harness now stores a loose
AnyAsyncMock for readChannelAllowFromStore but TelegramNativeCommandDeps
requires the precise typeof readChannelAllowFromStore signature. Cast at
the telegramDeps assignment so harness callers can keep passing any
vi.fn(...) (including ones that reject) without type pollution at the
call site.
* feat(telegram): reply with a retry hint when pairing-store read fails transiently
Wrap unexpected pairing-store I/O errors (EACCES, EMFILE, ...) in a
typed TelegramPairingStoreReadError and surface them through
handleInboundMessageLike with a friendly "please try again" reply that
matches the media-failure precedent at bot-handlers.runtime.ts:1893.
Beats silent drop: paired senders see why their message wasn't
processed, and unpaired senders who happen to send a DM during a
transient store outage retry naturally and get the correct pairing
prompt once the store recovers.
Verified live against @paxicoto_bot with chmod 000 on
~/.openclaw/credentials/telegram-default-allowFrom.json after touching
mtime to bypass the stat-pinned cache.
Summary:
- The PR updates the Unix installers to avoid emitting npm `--before` when raw npm config contains `min-releas ... records a changelog fix, and widens an internal model-catalog test helper type to accept sync auth checks.
- PR surface: Source +1, Tests +421, Docs +1, Other +150. Total +573 across 7 files.
- Reproducibility: yes. The linked report at https://github.com/openclaw/openclaw/issues/84743 gives an isolat ... exclusivity, and current main still has the source path that can generate the conflicting `--before` flag.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(installer): avoid before with npm release-age configs
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8549…
Validation:
- ClawSweeper review passed for head fb0762f468.
- Required merge gates passed before the squash merge.
Prepared head SHA: fb0762f468
Review: https://github.com/openclaw/openclaw/pull/85491#issuecomment-4522229812
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* perf(plugins): thread metadata snapshot and discovery through hot paths
With the snapshot memo now actually hitting, route the snapshot's
manifestRegistry and discovery through the helper chains that already
had fast paths for them. Eliminates redundant per-call rebuilds at
two big amplifiers.
- Provider resolve paths (resolvePluginProviders /
isPluginProvidersLoadInFlight / resolveOwningPluginIdsForProvider /
resolveExternalAuthProfilesWithPlugins) self-service a snapshot once
at the public entry, then thread it as a separate required arg
through resolvePluginProviderLoadBase,
resolveExplicitProviderOwnerPluginIds, and the setup/runtime load
state helpers. Inner reads change from
'params.pluginMetadataSnapshot?.x' to 'snapshot.x', no more
enrichedParams clone. loadPluginManifestRegistryForInstalledIndex
fires drop ~685 -> ~10 per cold start.
- Bundled-channel / auto-enable chain accepts an optional
PluginDiscoveryResult. discoverOpenClawPlugins is fired once during
snapshot building (resolveInstalledPluginIndexRegistry already
produced it internally; now bubbled up through
loadInstalledPluginIndexWithDiscovery, PluginRegistrySnapshotResult,
and onto PluginMetadataSnapshot.discovery). load-context reads
metadataSnapshot.discovery and passes it through
applyPluginAutoEnable, so the bundled-channel cascade
(collectConfiguredChannelIds, listBundledChannelIdsWith*,
listPotentialConfiguredChannelPresenceSignals) short-circuits
instead of each leaf re-firing discovery. Persisted-cache path is
unchanged: no discovery on the snapshot, downstream chain handles
its own fallback (pre-PR behavior on that path).
* test(plugins): isolate snapshot memo across tests that mock manifest registry
The snapshot memo is now process-scoped and effective (~98% hit rate).
Three test files were depending on cache misses (because the broken
cache returned them) — each test would set up its own
loadPluginManifestRegistry mock and expect a fresh derive. With the
cache fixed, an earlier test's mocked registry now leaks into later
tests in the same file.
- io.write-config.test.ts: afterEach now clears the snapshot memo so
the 'demo' plugin mocked in the first test does not survive into
'keeps shipped plugin install config records when index migration
fails', which expects an empty registry to surface the 'plugin not
found: demo' warning.
- gateway/model-pricing-cache.ts: resetGatewayModelPricingCacheForTest
also clears the memo. Tests in model-pricing-cache.test.ts assert
loadPluginManifestRegistryForInstalledIndex was called; the memo
hit otherwise skips the call.
- providers.test.ts: vi.doMock loadPluginMetadataSnapshot to wrap the
existing loadPluginManifestRegistryMock fixture. The plumbing
commit added an auto-fetch fall-through in
resolveOwningPluginIdsForProvider; without the mock, providers
tests hit real disk reads and return empty registries (which is
what surfaced as 9 unrelated-looking failures in the prior CI
run).
* fix(plugins): preserve setup.cliBackends owner matching in provider scan
resolveOwningPluginIdsForProvider now also checks plugin.setup?.cliBackends.
The pre-PR no-registry fallback used resolvePluginContributionOwners which
includes both top-level cliBackends and setup.cliBackends; the PR's manifest
scan replacement was missing the setup case.
* fix(plugins): inherit active registry workspaceDir before loading metadata snapshot
isPluginProvidersLoadInFlight and resolvePluginProviders now resolve
env and workspaceDir once at the entry point (falling back to
getActivePluginRegistryWorkspaceDir) and pass them into both
loadPluginMetadataSnapshot and resolvePluginProviderLoadBase. Pre-fix
the snapshot used params.workspaceDir raw while the load base inherited
the active workspace, so workspace-scoped provider plugins could be
absent from the snapshot manifest registry even though owner resolution
expected them.
Regression test asserts the snapshot mock receives the active
workspaceDir when the caller omits it.
* perf(gateway): thread discovery into applyPluginAutoEnable call sites
Every gateway applyPluginAutoEnable call now passes the snapshot's
PluginDiscoveryResult so the bundled-channel cascade (collectConfiguredChannelIds
→ listBundledChannelIdsWith* → listPotentialConfiguredChannelPresenceSignals)
short-circuits instead of each leaf re-firing discovery.
Startup-time sites pull discovery from the snapshot/lookup-table they already
hold:
- server-plugin-bootstrap.ts (pluginLookUpTable)
- server-startup-plugins.ts (pluginMetadataSnapshot)
- server-startup-config.ts (pluginMetadataSnapshot)
- server-plugins.ts (pluginLookUpTable, both call sites)
Per-RPC sites (server.impl getRuntimeConfig callback, server-methods/channels
status + start handlers, server-methods/send) source discovery via
getCurrentPluginMetadataSnapshot using the runtime config to validate
compatibility. Falls through to the original slow path when the snapshot is
absent or incompatible.
Summary:
- The branch adds a 1500 ms internal timeout to bundled MCP `tools/list` catalog discovery, adds slow and hung stdio MCP regression tests, and records the fix in `CHANGELOG.md`.
- PR surface: Source +2, Tests +216, Docs +1. Total +219 across 3 files.
- Reproducibility: yes. The current-main source path is high confidence: bundled MCP connects successfully, then calls `client.listTools` without request options, and the upstream SDK defaults that request to 60000 ms.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(mcp): use internal tools list timeout
- PR branch already contained follow-up commit before automerge: fix(mcp): bound tools/list during catalog discovery
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8506…
Validation:
- ClawSweeper review passed for head bbbfb9f059.
- Required merge gates passed before the squash merge.
Prepared head SHA: bbbfb9f059
Review: https://github.com/openclaw/openclaw/pull/85063#issuecomment-4511554739
Co-authored-by: nxmxbbd <32288+nxmxbbd@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* feat(imessage): support thumb approval reactions
Mirrors openclaw#85477 (WhatsApp) for the iMessage channel. iMessage can now
deliver exec/plugin approval prompts via the existing imsg/BlueBubbles
transport and resolve approvals from 👍 (allow-once) / 👎 (deny) tapbacks.
Allow-always remains on the manual /approve <id> allow-always fallback.
What changed:
- New approval surfaces under extensions/imessage/src/:
approval-auth.ts, approval-resolver.ts, approval-reactions.ts,
approval-handler.runtime.ts, approval-native.ts (+ tests for each).
- channel.ts wires base.approvalCapability to the new iMessage capability.
- send.ts appends the 👍/👎 hint to outbound /approve prompts and registers
the reaction binding (keyed by accountId + chat_guid/chat_identifier/
chat_id/handle + messageId) after a successful send.
- monitor/monitor-provider.ts resolves approval reactions ahead of the
normal inbound decision pipeline so resolution bypasses
reactionNotifications gating and runs its own actor authorization.
- runtime.ts now exports getIMessageRuntime / getOptionalIMessageRuntime so
approval-reactions can open a persistent keyed store for binding state
across gateway restarts.
What did NOT change:
- Core approval surfaces in src/gateway/server-methods/* and src/infra/*
remain channel-agnostic; the channels.imessage.allowFrom field already
exists and is reused as the approver list for reactions.
- Other channels and the manual /approve sender-authorized path are
untouched.
* fix(imessage): address codex review findings on thumb approvals
Addresses 15 findings from the multi-angle codex review:
Critical (correctness / blocking):
- Register CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY in the iMessage
monitor so the gateway can actually deliver native approval prompts via
approval-handler.runtime.ts (it was dead code without the context lease).
- DM tapback approvals never resolved because send keyed by handle while
inbound preferred chat_guid. Register and look up under EVERY available
conversation key (chat_guid / chat_identifier / chat_id / handle); inbound
probes them all and accepts the first hit.
- Reaction binding now requires the bridge's GUID string (rejecting numeric
ROWIDs) so the binding key matches inbound reacted_to_guid.
- Outbound regex now requires both a canonical `ID: <approvalId>` header AND
a matching `/approve <id> <decision>` line, so non-approval messages that
legitimately mention /approve syntax no longer get a phantom reaction
binding (and can no longer resolve a colliding live approval).
- Drop is_from_me reaction events so cross-device echoes of the operator's
own tap cannot self-approve when their handle is in allowFrom.
High (operability / cleanup):
- Non-ApprovalNotFound errors now log at warn via the runtime child logger
(no longer hidden behind OPENCLAW_LOG_LEVEL=debug).
- In-memory binding is cleared on successful resolve so a toggle 👍→👎 (or
chat.db replay) does not refire and emit a misleading 'expired approval'
log line. Removed tapbacks are also owned by the shortcut and not surfaced
as noisy reaction system events.
- Move resolveIMessageReactionContext (and its helpers) to a slim
monitor/reaction-context.ts so approval-reactions.ts no longer transitively
pulls monitor/inbound-processing.ts (14+ heavy runtime modules) into the
hot channel.ts entrypoint per extensions/CLAUDE.md.
Medium (consistency / future-proofing):
- Native runtime exec pending payload now passes agentId, ask, and
sessionKey through buildExecApprovalPendingReplyPayload so the two
delivery routes produce identical operator-visible prompts.
- Both delivery paths now use addIMessageApprovalReactionHintToText (single
insertion point after ID:) so the hint cannot be double-emitted by the
native runtime path bypassing the idempotency guard.
- Extract replaceApprovalIdPlaceholder into a shared approval-text.ts that
escapes `$` in the replacement string so an approvalId containing
`$&`/`$1`-`$9`/`$$` cannot interpolate into the outbound text.
- In-memory Map now stores TTL alongside each entry and prunes expired
bindings on each register so the gateway no longer accumulates an
unbounded reaction-target Map.
- bindPending refuses to bind when accountId is missing or the approval is
already expired, with explicit error logs instead of silent no-ops.
- Reject chat_id=0 as a synthetic key value (chat.db ROWIDs start at 1).
- Drop dead getIMessageRuntime export — only the optional accessor is used.
Documentation:
- docs/channels/imessage.md gains an 'Approval reactions (👍 / 👎)' accordion
documenting the reaction emoji map, allowFrom approver requirement, the
/approve <id> allow-always manual fallback, and the deliberate change to
/approve command authorization for users with non-empty allowFrom.
- CHANGELOG.md entry added under 2026.5.24.
Tests: 411 iMessage tests pass (was 406). Added explicit coverage for the
DM key-mismatch fix, the regex-tightening fix, the is_from_me guard, the
clear-on-success behavior, and the approval-id `$` escape.
* test(imessage): match WhatsApp approval-native test coverage
Backfills the nine cases from extensions/whatsapp/src/approval-native.test.ts
that weren't mirrored in iMessage:
- target-mode exec + plugin prompt rendering with the canonical hint
- target-mode availability when no iMessage target matches
- agentFilter / sessionFilter applied to native handling
- account-scoped target enabled/disabled per account
- shouldSuppressForwardingFallback session-origin exact-match cases
- shouldSuppressForwardingFallback off when native cannot bind (locks down
the targets-only forwarding path the Lobster live deploy exercised)
- both-mode explicit + unscoped target suppression
- group-origin tapback approvals require explicit approvers
Tests: extensions/imessage/src/approval-native.test.ts 21 passed (was 11).
Total iMessage approval-specific cases now 49 (was 40).
* fix(imessage): preserve service-prefixed direct handles as approvers
ClawSweeper P1 review finding on #85952. normalizeIMessageApproverId was
calling looksLikeIMessageExplicitTargetId() to reject conversation-target
prefixes, but that helper also matches the imessage:/sms:/auto: service
prefixes — which are valid direct-handle forms. Any allowFrom entry like
'imessage:+15551230000' dropped to undefined, leaving approvers empty,
which:
- silently denied reaction resolution ('reactions require explicit
approvers'), and
- let text /approve fall back to implicit same-chat authorization.
Fix: normalize first via normalizeIMessageHandle (strips the service
prefix), then reject only chat_id:/chat_guid:/chat_identifier:
conversation-target shapes that remain after normalization.
Tests:
- approval-auth.test.ts: assert the resolved approver list contains the
normalized handle, plus the corollary that a non-matching sender is
explicitly rejected (no longer masked by the implicit-same-chat
fallback). Add a separate case covering chat_id/chat_guid/
chat_identifier rejection (with and without a service prefix).
- approval-reactions.test.ts: reaction resolution end-to-end with a
service-prefixed allowFrom entry — proves resolveIMessageApproval is
called rather than silently denied.
Focused suite: 48 passed (was 47).
* test(imessage): satisfy strict buildPendingPayload signature in render tests
CI check:test-types caught that the render.exec/render.plugin
buildPendingPayload calls were passing accountId (not in the type
signature). The signature is { cfg, request, target, nowMs }. Replace
accountId with target on the four render-test sites so the strict
test-types pass matches the SDK contract:
- it('renders thumbs-only reaction hints in exec approval prompts')
- it('renders thumbs-only reaction hints in plugin approval prompts ...')
- it('renders target-mode exec prompts with concrete thumbs-only ...')
- it('renders target-mode plugin prompts with concrete thumbs-only ...')
Verified locally with pnpm check:test-types (tsgo:core:test +
tsgo:extensions:test). 49 approval-specific tests still pass.
* fix(imessage): probe every tapback GUID form for approval lookup
ClawSweeper P1 review finding on #85952. readApprovalReactionEvent was
only using reaction.targetGuid (the first/normalized form), but
resolveIMessageReactionContext produces reaction.targetGuids = [normalized,
raw] for both `abc-123` and `p:0/abc-123` forms. If the imsg bridge
returned 'p:0/<guid>' from send() and send.ts registered the binding under
that prefixed key, the inbound resolver probing only the unprefixed form
would miss and the tapback would silently fall through.
Fix:
- Surface every GUID candidate in IMessageApprovalReactionEvent
(messageIdCandidates).
- maybeResolveIMessageApprovalReaction now probes each candidate in
precedence order; first hit wins.
- On success / ApprovalNotFoundError, clear the binding under all
candidate keys so toggle/replay does not refire.
Tests: extensions/imessage/src/approval-reactions.test.ts gains a
'resolves a reaction when the binding was registered under a p:0/…
prefixed GUID and the tapback surfaces both forms' regression case;
22/22 reaction tests pass. Full iMessage suite: 424/424.
* fix(imessage): native approval binding requires GUID, not numeric id
ClawSweeper third P1 review finding on #85952. approval-handler.runtime.ts
deliverPending was using result.messageId as the approval-reaction binding
key, but that field can be a numeric ROWID coerced to a string ('12345')
when the imsg bridge returns only message_id. Inbound tapbacks carry
reacted_to_guid which is always a GUID, so a numeric-id binding can never
match.
Fix mirrors the send.ts forwarding-path treatment:
- IMessageSendResult now exposes a separate guid?: string field, populated
from the same resolveOutboundMessageGuid helper send.ts already uses for
the forwarding-path binding. The generic messageId field is unchanged so
reply-cache, echo-cache, and receipt-building paths still see the
broadest id form.
- deliverPending now binds against result.guid; when it's undefined (numeric
ROWID or 'ok'/'unknown' placeholders), the function returns null instead
of binding against an id the inbound tapback can't possibly match.
Tests: approval-handler.runtime.test.ts gets a deliverPending GUID-only
binding describe block with three regression cases (numeric ROWID refused,
GUID accepted, ok/unknown placeholders refused). vi.mock isolates
sendMessageIMessage so the cases run synchronously without spawning imsg.
11 tests pass across handler.runtime + send specs.
---------
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Summary:
- The branch updates OpenRouter dynamic model capability parsing to prefer `top_provider.context_length`, bump ... sk cache version, adds regression coverage and a changelog entry, and adds script helper declaration files.
- Reproducibility: yes. from source and live catalog evidence rather than an authenticated inference turn. Cur ... catalog currently reports a smaller endpoint-specific `top_provider.context_length` for the reported model.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(openrouter): use endpoint context limits
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8594…
Validation:
- ClawSweeper review passed for head 76fcc362d2.
- Required merge gates passed before the squash merge.
Prepared head SHA: 76fcc362d2
Review: https://github.com/openclaw/openclaw/pull/86041#issuecomment-4528646655
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR changes dev-channel git updates to fetch branches with `--no-tags`, adds targeted fetching for explicit dev tag refs, updates update-runner tests, and adds a changelog entry.
- Reproducibility: yes. Current main source shows dev updates still run a broad tag fetch, and the PR body sup ... al local bare-remote moved-tag reproducer showing that command fails before the branch update can continue.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(update): avoid broad tag fetches for dev updates
Validation:
- ClawSweeper review passed for head 733680b1bc.
- Required merge gates passed before the squash merge.
Prepared head SHA: 733680b1bc
Review: https://github.com/openclaw/openclaw/pull/84737#issuecomment-4503692161
Co-authored-by: Ruben Cuevas <hi@rubencu.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
The agentToAgent allow-pattern matcher converted user wildcards like
`*a*b*c*` into `^.*a.*b.*c.*$` via RegExp. Multiple overlapping
`.*` groups cause O(n^k) polynomial backtracking against non-matching
input, where k is the number of wildcards.
Replace the regex path with a segment-based glob matcher that splits on
`*` and checks prefix/suffix/interior segments in order. The new
matcher runs in O(n*k) worst case and eliminates the regex engine
entirely from this path.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(minimax): normalize OAuth token expiry to absolute millisecond timestamp
MiniMax returns expired_in from the token endpoint as a relative duration
in seconds (standard OAuth expires_in semantics), but the auth profile
store's hasUsableOAuthCredential() expects an absolute millisecond
timestamp. Without conversion the token appears perpetually expired,
triggering a slow OAuth refresh network call to api.minimaxi.com on
every request — the root cause of the 30-50s auth-stage delay.
Fixes#83449.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(minimax): cover oauth expiry normalization
* fix: polish minimax oauth expiry normalization (#83480) (thanks @NianJiuZst)
* fix: update minimax raw fetch allowlist (#83480)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The branch updates gateway boot startup handling to use an `agent:<id>:boot` session, suppress prompt persis ... that boot mapping after the run, and adds focused gateway boot regression coverage plus a changelog entry.
- Reproducibility: yes. there is a high-confidence source reproduction path: current main passes the generated ... idence of repeated persisted boot prompts. I did not execute the gateway scenario in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Fix boot-md test lint
- PR branch already contained follow-up commit before automerge: Isolate boot-md startup sessions
Validation:
- ClawSweeper review passed for head 5d5338c2d9.
- Required merge gates passed before the squash merge.
Prepared head SHA: 5d5338c2d9
Review: https://github.com/openclaw/openclaw/pull/85919#issuecomment-4527318708
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Clamp proxy-like OpenAI Chat Completions output caps against the estimated final outbound request payload after compatibility transforms. This prevents strict local/API-compatible servers from rejecting requests whose prompt already consumes part of the effective context window, while avoiding over-clamping dropped replay turns.
Co-authored-by: rendrag-git <253747599+rendrag-git@users.noreply.github.com>
Honor configured restart drain budgets for embedded runs and avoid a second active-work drain after forced deferral timeout restarts.
Includes maintainer changelog entry.
* fix(ui): handle empty strings with minLength constraint in config save
Fixes#85831
When saving config in Control UI, required string fields with minLength
constraint (e.g., z.string().min(1)) were sent as empty strings instead
of being unset. This prevented schema defaults from applying.
Solution: coerce empty strings with minLength > 0 to undefined, allowing
schema defaults to take effect during validation.
Added 5 unit tests covering edge cases.
* fix(types): add minLength and maxLength to JsonSchema type
Keep successful Codex native hook relays alive through a bounded grace window so late hook callbacks still reach OpenClaw enforcement, while interrupted, aborted, timed-out, and failed turns unregister immediately.\n\nCo-authored-by: Kaspre <kaspre@gmail.com>
Summary:
- The PR adds the Chrome DevTools MCP `--no-usage-statistics` default launch arg, honors explicit profile usage-statistics `mcpArgs`, adds regression tests, and adds a changelog entry.
- Reproducibility: yes. source-reproducible: current main builds Chrome MCP launch args without the upstream o ... etry is initialized. I did not run a fresh failing current-main process leak loop in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Disable Chrome MCP telemetry watchdog by default
Validation:
- ClawSweeper review passed for head 68249b1f58.
- Required merge gates passed before the squash merge.
Prepared head SHA: 68249b1f58
Review: https://github.com/openclaw/openclaw/pull/85886#issuecomment-4526997996
Co-authored-by: Rohit <rohitjavvadi2@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Restore the describeImageWithModel default token budget to the helper-level 4096-token default instead of forcing 512 before resolution.
Add regression coverage for the default and for smaller model caps, and record the user-facing fix in the changelog.
Co-authored-by: scotthuang <scotthuang@tencent.com>
* fix(doctor): repair stale contextWindow for DeepSeek V4 Flash
Problem:
- Older releases configured deepseek-v4-flash with contextWindow: 200000
- Official DeepSeek V4 Flash context window is 1,000,000 (1M)
- Users switching from smaller models see incorrect progress bar (e.g.,
50% instead of 10%) because stale config value overrides catalog
Fix:
- Add 'models.providers.*.models.*.contextWindow-stale' migration
- Detects deepseek-v4-flash models with 200K contextWindow
- Repairs to 1M to match catalog default
- Handles both bare and provider-prefixed model IDs
- 7 unit tests covering repair, passthrough, edge cases
Fixes: #85834
* fix(doctor): preserve custom DeepSeek context windows
* fix(doctor): detect stale DeepSeek context windows
* fix(doctor): scope DeepSeek context repair
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): broadcast error to UI when chat.send fails synchronously
* test(gateway): verify broadcastChatError is called on chat.send error
* test(gateway): import GatewayRequestContext from local server-methods barrel
Fixes the chat error-broadcast regression test so it can resolve its
type import. The previous `../types.js` path does not exist in the
gateway tree; the shared types are re-exported from
`src/gateway/server-methods/types.ts`, so the test must use `./types.js`.
Addresses ClawSweeper review on PR #85815.
---------
Co-authored-by: scotthuang <scotthuang@tencent.com>
createAuthProvider swallowed addUserForToken rejections in a .catch()
that only logged, so getClient returned and cached a ChatClient backed
by a RefreshingAuthProvider with no bound user. The failure surfaced
later as an opaque auth error on first send instead of failing fast.
Re-throw in the catch so getClient rejects and does not cache the broken
client. Adds regression tests for the rejection and the no-cache behavior.
Fixes#83853
Summary:
- The PR skips agent-harness compaction preflight for provider-owned or configured CLI runtime sessions, adds claude-cli regression coverage, includes a changelog entry, and applies small test/type cleanups.
- Reproducibility: yes. at source level. Current main still routes provider-owned `claude-cli` runtime compaction preflight through harness selection, where `claude-cli` is not a registered embedded harness.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix#84857: skip CLI runtime harness preflight during compaction
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8487…
Validation:
- ClawSweeper review passed for head 1dd8a88d21.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1dd8a88d21
Review: https://github.com/openclaw/openclaw/pull/85862#issuecomment-4526794976
Co-authored-by: 张贵萍0668001030 <zhang.guiping@xydigit.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* fix(session-lock): enforce maxHoldMs in shouldReclaim during lock acquisition
- Adds optional maxHoldMs parameter to inspectLockPayload
- Inspect now marks locks as stale when held longer than maxHoldMs
- Passes maxHoldMs through inspectLockPayloadForSession
- acquireSessionWriteLock's shouldReclaim callback now passes maxHoldMs
This ensures that when a live process holds a lock for longer than
maxHoldMs (default 5min), other processes can reclaim it during
acquisition — matching the watchdog's existing enforcement.
Previously shouldReclaim only used staleMs (30min default), meaning
a lock held for 10+ minutes by a live PID would never be reclaimable,
causing 60s timeout failures and gateway freezes.
Closes#85762
* fix(session-lock): add dead-PID fast-path before retry loop
Adds a fast-path check at the top of acquireSessionWriteLock:
if the lock file's owner PID is dead, remove it immediately
before entering the retry loop. This saves up to timeoutMs (60s)
of futile waiting when the previous lock holder has died.
The shouldReclaim callback already handles this case, but only
iteratively through the retry loop. The fast-path eliminates
that unnecessary delay.
* fix(session-lock): enforce max hold during acquisition
* fix(session-lock): revalidate max hold safely
* fix(session-lock): honor holder max-hold policy
* fix(session-lock): keep cleanup from reclaiming live holders
* fix(session-lock): remove stale locks only when unchanged
* fix(session-lock): skip self-held max-hold reclaim
* fix(ci): refresh gateway protocol checks
---------
Co-authored-by: njuboy11 <njuboy11@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars
`buildCliSessionHistoryPrompt` was prefix-slicing the rendered history,
dropping the most recent assistant turns from the reseed prompt. After
#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is
exposed to this on session_expired when the rendered transcript exceeds
12288 chars. The truncation marker landed mid-word in real reproductions.
Fix:
- Tail-slice (keep the recent suffix, drop the older prefix)
- Pin the compaction summary as a prefix when present, only cap the
post-summary transcript (loadCliSessionReseedMessages deliberately
places the summary first)
- When the summary alone exceeds maxHistoryChars, head-slice the summary
itself to honor the cap; drop the post-summary tail in that case
- Move the truncation marker to the lead since what follows is the
recent tail, not what was dropped
Closes#83157
* fix(cli-runner): retain recent tail with oversize summaries
* fix(cli-runner): cap summary block plus marker against maxHistoryChars
ClawSweeper P2 on #83117 flagged that when `summaryRendered.length` is
less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n`
separator) meets or exceeds it, the `remainingBudget <= 0` arm of
`buildCliSessionHistoryPrompt` appends the truncation marker after the
already-full summary block. A 199-char rendered summary under a 200-char
cap produced a 257-char history block — defeating the cap that prevents
reseeding fresh CLI sessions with unexpectedly huge prompts.
Fix the budget edge by truncating the summary in this branch as well so
`summary + separator + marker` stays within `maxHistoryChars`. The tail
still drops (the summary alone consumes the budget) and the marker still
leads its own line so the prompt announces what was discarded. Mirrors
the existing oversize-summary branch's pattern of head-slicing the
summary against an explicit budget that reserves marker + separator.
Add a focused regression in `session-history.test.ts` covering exactly
the gap the finding called out: `summaryRendered.length < maxHistoryChars`
with a non-empty post-summary tail. Asserts the rendered history block
stays within `maxHistoryChars` and the truncation marker is present.
* fix(cli-runner): keep tail for near-cap summaries
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The auto-reply "delivery failed" log path passes a raw Error
under the `err` field. tslog's default JSON serialization
renders bare Error instances as `{}` because Error own data
properties are non-enumerable. Every delivery failure in
production therefore logs `err: {}`, forcing operators to
guess the underlying Baileys error from timestamp alone.
Convert Error to `{ type, message, stack }` plus own-enumerable
properties at the log site, so Boom-style subclass diagnostics
(output.statusCode, data) and custom OutboundDeliveryError
fields (stage, results) survive. Non-Error rejection values
pass through unchanged.
Tests cover Error, Error subclass (Boom-style), string
rejection, and object rejection paths.
AI-assisted: Claude Code (Opus 4.7) authored, codex review
locally addressed.
Strict OpenAI-compatible servers (vLLM, LocalAI, llama.cpp, LM Studio) and
current OpenAI itself reject requests containing tools: []. Strip the empty
tools array (and the orphan tool_choice) from outbound chat-completions
payloads when usesExplicitProxyLikeEndpoint is true. Native OpenAI/Azure/
OpenRouter routes are byte-identical.
Supersedes #70790 at the canonical payload builder seam so the gateway,
embedded runner, and public plugin-SDK consumers (zai/xiaomi/deepseek) all
benefit.
* codex: honor verbose in group dispatch
* codex: address group verbose review findings
Record the final local review pass for the group /verbose PR.
Codex review against origin/main completed clean after tightening the shared group progress gate, keeping public plugin hook types stable, preserving ACP hidden tool boundaries, and adding regressions for live verbose gating and progress-callback suppression.
* codex: require explicit group verbose progress
Normal group tool/progress summaries now require an explicit session verbose override instead of inherited agent verbose defaults.
This addresses the PR review concern that existing verboseDefault configurations could expose group progress after upgrade. DMs and forum-topic behavior continue to use the effective verbose state, while normal groups use the live explicit session verbose state set by /verbose on|full|off.
* codex: document Slack group verbose caveat
* fix(channels): simplify verbose progress gating
* docs(changelog): note verbose channel fix
* fix(channels): preserve quiet default for group progress
* fix(channels): keep verbose error policy dynamic
* fix(channels): default verbose progress off everywhere
* fix(channels): keep followup verbose default quiet
* fix(channels): latch visible tool-error progress
* fix(channels): track failed verbose progress events
* fix(channels): latch delivered tool errors
* fix(channels): prevent progress opt-out bypass
* fix(channels): isolate followup error warning state
* fix(channels): keep full verbose followup warnings
* fix(channels): latch tool errors after visible progress
* fix(channels): require visible followup failure progress
* fix(channels): refresh followup verbose state
* fix(channels): honor live verbose for error details
* test(channels): expect live verbose off warning mode
* fix(channels): preserve static tool error suppression semantics
* fix(channels): bypass acp for colon verbose commands
* fix(channels): narrow dynamic tool warning override
* fix(channels): gate compaction notices on live verbose
* fix(channels): suppress quiet followup compaction callbacks
* fix(channels): suppress tts for hidden tool summaries
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The PR removes forced consult diagnostics from Discord and phone-call realtime consult payloads, adds private debug logs and regression tests, and records the fix in the changelog.
- Reproducibility: yes. by source inspection. Current main builds the forced Discord consult message with the ... gent_consult` diagnostic string, and the phone-call fallback passes the same diagnostic as consult context.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(discord): log forced consult fallback reason
- PR branch already contained follow-up commit before automerge: fix(discord): keep forced voice consult diagnostics private
Validation:
- ClawSweeper review passed for head c1592530c6.
- Required merge gates passed before the squash merge.
Prepared head SHA: c1592530c6
Review: https://github.com/openclaw/openclaw/pull/84411#issuecomment-4494164784
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Expose a path-free estimated context budget status on session entries and gateway session rows, render it in status when fresh provider usage is unavailable, and clear stale estimates across reset, refresh, compaction, and session-rotation boundaries.
Verification: focused local Vitest covered session persistence, status rendering, gateway rows, model resets, compaction, and session rotation; GitHub CI passed on clean head cad199e43d.
Refs #80594, #54996, #77992, #84490, #83177, #43009, #83526, #8635.
* fix: harden package URL downloads
Guard package acceptance URL downloads with HTTPS-only validation, no embedded credentials, private/special-use DNS and IP rejection, manual redirect checks, bounded timeout/size limits, pinned lookup, and atomic temp-file writes. Add tooling tests for unsafe URLs, redirect validation, size limits, and successful writes.
* fix: cancel redirect response bodies before closing dispatcher
ClawSweeper P2: the redirect branch in openPackageDownloadResponse cleared
the timeout and awaited dispatcher.close() without first cancelling
response.body. Undici's close() is graceful — it waits for in-flight
requests to complete — so a malicious redirect with a slow/never-ending
body could hang the hardened downloader.
Fix: call response.body?.cancel() before dispatcher.close() to abort the
redirect body immediately.
Test: add a regression test that uses a ReadableStream with an indefinite
interval to simulate a hanging body, and asserts cancel() was called.
Refs: clawsweeper review on PR #85512
* test: harden redirect body cancellation race in regression test
Guard the ReadableStream controller.enqueue() call with a cancelled
flag and try/catch to prevent ERR_INVALID_STATE when the interval
fires after cancel() closes the controller.
* fix: cancel final response body before closing dispatcher in downloadUrl
ClawSweeper P2: the HTTP-error and declared-oversize early-exit paths
in downloadUrl threw before consuming or canceling response.body. The
finally block then cleared the timeout and awaited graceful
dispatcher.close() with the body still open, allowing a slow/never-ending
response to hang release tooling.
Fix: add response.body?.cancel() in the finally block before
dispatcher.close().
Tests: add two regressions:
- HTTP 500 with slow body: asserts cancel() called before dispatcher close
- Declared content-length oversize with slow body: same assertion
* fix: add trusted package URL source policy
* fix: keep package URL resolver dependency-free
* test: cover encoded IPv6 package URL bypasses
* docs: sync package acceptance source overview
* docs: restore release doc formatting
* docs: sync package acceptance trusted-url source
* test: cover dotted IPv4 embedded IPv6 package URLs
* fix: parse dotted IPv4 embedded in IPv6 package URLs
* test: isolate anthropic pruning defaults
* test: move anthropic dated model coverage
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(exec-approvals): add .catch() to expiry delivery fire-and-forget
When exec-approval expiry fires, deliverToTargets is called as a
fire-and-forget promise with no .catch(). If delivery fails, the
unhandled rejection swallows the error and the notification is lost.
Add .catch() with log.warn to match the ackDelivery error handling
pattern. Keep pending.delete() before the await (the entry is expired
regardless of delivery success).
Closes#83113
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(approvals): label expiry delivery errors by kind
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(doctor): skip empty entries and memoize routes in plugin session repairs
runPluginSessionStateDoctorRepairs called resolveConfiguredDoctorSessionStateRoute
once per session-store key, even for entries that carry no plugin route state
fields. On stores with many CLI sessions (observed ~800 entries), each call
takes ~1.5s due to resolveAgentHarnessPolicy walking config and provider
metadata, so the doctor's state-integrity contribution hangs for minutes
and the surrounding 'openclaw doctor' run effectively never completes.
scanEntryForOwner can only produce repair/manual-review findings when the
entry exposes one of the fields covered by entryMayContainPluginSessionRouteState
(providerOverride/modelOverride/agentHarnessId/cliSessionBindings/etc.), so
the route resolution for empty entries was pure waste. The route itself is
also a function of agentId (sessionKey is only used to derive agentId), so
sessions sharing an agent can reuse one resolved route.
Filter the store by entryMayContainPluginSessionRouteState before resolving,
and memoize resolveConfiguredDoctorSessionStateRoute by agentId within the
remaining entries. On the repro store this drops the contribution from
'never completes' to <100ms.
Adds a guard test that builds a 200-entry store with 2 route-state-carrying
entries and asserts (a) the repair fires exactly once on the codex owner
and (b) the run completes in under 2s (pre-fix would take >5 minutes).
* fix(doctor): skip manifest model-id normalization in plugin session repairs
After the previous filter+memoize fix, runPluginSessionStateDoctorRepairs was
still ~38s on a 230-entry store because every scanned entry calls parseModelRef
on its runtime model. That implicitly enters manifest-driven model-id
normalization via normalizeStaticProviderModelId, which calls
loadPluginMetadataSnapshot when no current snapshot is bound to process state.
loadPluginMetadataSnapshot is filesystem-heavy and is only memoized when a
'current' snapshot is bound (it is not, during doctor), so each parseModelRef
call paid ~40ms of fresh plugin-metadata loading. 672 calls × ~40ms = ~27s
of doctor wall-clock, all of it useless for doctor's purposes: the scan only
needs the normalized provider id of the configured runtime/route to compare
against an owner's providerIds, never the manifest-normalized model id.
Pass allowManifestNormalization: false alongside the existing
allowPluginNormalization: false on all three parseModelRef call sites in
this file. normalizeStaticProviderModelId short-circuits to
normalizeBuiltInProviderModelId when allowManifestNormalization is false,
which is what doctor wants here.
On the same 230-entry store doctor:state-integrity drops from ~38s to ~2.4s
and total openclaw doctor wall-clock drops from ~91s to ~56s.
Consume the existing { text, changed } signal from
stripInlineDirectiveTagsForDisplay so unchanged text-parts keep their
references and the original message is returned when nothing was
stripped. Avoids spurious downstream rerenders/diff churn for consumers
relying on reference equality, and keeps the public SDK helper's text
output and message shape stable.
Fixes#37589.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
openai-codex-responses can return turns where usage.output > 0 but
assistantTexts is empty (hidden reasoning tokens only). The empty
response retry guard only covered openai-completions, anthropic-messages,
and Ollama, so these turns passed through as successful completions
with no content delivered to the user.
Add the full openai-responses API family (openai-responses,
openai-codex-responses, azure-openai-responses, and their transport
variants) to RETRY_GUARD_MODEL_APIS so the empty response and
reasoning-only retry paths can fire for these providers.
Closes#85364
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(status): show configured cost for aws-sdk models
Decouple status cost display from provider auth mode so explicit model pricing is used for Bedrock and other non-api-key providers. Include cache read/write tokens in the status cost estimate and cover the behavior with regression tests.
* fix: show configured response usage costs
* docs: align configured cost visibility
* fix(status): keep usage tokens mode cost-free
---------
Co-authored-by: ItsOtherMauridian <165866613+ItsOtherMauridian@users.noreply.github.com>
Co-authored-by: ItsOtherMauridian <itsothermauridian@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
When onboarding Microsoft Foundry-hosted DeepSeek-V4 models (Pro/Flash),
the onboarding wizard assigned api: 'openai-completions' because
usesFoundryResponsesByDefault() only matched GPT/o-series models.
These V4 models require the Responses API (openai-responses) to work
correctly against the Foundry endpoint. Without this fix, all calls fail
with 'provider rejected the request schema or tool payload'.
Fix: Add 'deepseek-v4' prefix to usesFoundryResponsesByDefault() so only
the verified V4 family defaults to openai-responses. Older DeepSeek
families (e.g., V3) remain on openai-completions until proven compatible.
Closes: DeepSeek V4 models deployed via Microsoft Foundry onboarding
failing immediately due to wrong API adapter.
Co-authored-by: Roslin <rmj010203@gmail.com>
Defer Gateway channel startup until after readiness, remove startup model prewarm, and move model catalog data onto manifest/static paths so startup no longer loads broad provider runtimes.
Verification:
- focused gateway/catalog/auth/QA Vitest runs
- autoreview clean
- Blacksmith Testbox-through-Crabbox tbx_01ksahn65rsrsqz3q1qyxwf929: pnpm check:changed, exit 0
- PR CI green on ee2b631c72
* fix(gateway): normalize explicit state dir overrides at startup
* test(gateway): simplify state-dir startup coverage
* test: fix state dir startup coverage
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Route cron announce topic target parsing through channel plugin target parsers instead of Telegram-specific cron core code. Keep supported Telegram topic forms in the Telegram plugin and document the channel-owned shorthand.
* fix(bootstrap): guard bootstrap name checks against undefined names
Add optional chaining to isAgentsBootstrapFile and isAgentsBootstrapName
to prevent TypeError: Cannot read properties of undefined (reading 'toLowerCase')
when bootstrap file entries have undefined name properties.
This crash was observed in 2026.5.20 where a workspace bootstrap file entry
with an undefined name caused every incoming message to fail during bootstrap
context building, completely blocking all agent replies.
Fixes#85523
* test(agents): cover unnamed bootstrap truncation entries
* test(agents): keep bootstrap truncation fixture typed
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
`waitForever()` is a public library export used by long-running embeds to
block until the host process is asked to exit. It called `interval.unref()`
on the keep-alive timer, which removes the timer from Node's active-handle
set. With no other ref'd handles, `await waitForever()` exits the process
in ~3ms with exit code 13 ("unsettled top-level await") instead of waiting.
Drop the `.unref()` so the interval actually keeps the loop alive, and
update the existing unit test (and comment) to lock in the new contract.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix(cli-output): ignore cumulative usage from result events in stream-json parser
Claude-cli's stream-json result event reports cumulative cache_read across
all tool sub-calls, not the per-call value. The parser was overwriting the
last assistant-event usage with this inflated sum, causing sessionEntry.totalTokens
to climb 6-13x on tool-heavy turns and trip the preemptive-compaction gate.
Fix: skip reading usage from result events in createCliJsonlStreamingParser,
keeping the last per-call usage from assistant events instead.
Fixes#85573
* fix(agents): keep Claude result usage as fallback
* fix(agents): read Claude assistant stream usage
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Fixes#83883.
In `secrets configure`, the one-way-migration irreversibility warning was
computed from `opts.apply` (the original --apply flag) rather than
`shouldApply`. On the interactive path the user confirms "Apply this plan
now?", which sets shouldApply=true while opts.apply stays false, so the
warning was silently skipped and the irreversible plaintext migration was
applied without the second confirmation.
Derive the guard from shouldApply so the irreversibility warning fires on
both the --apply path and the interactive-confirm path. Adds regression
tests covering the interactive path (warning shown; declining it cancels
the apply).
* fix(agents/harness): pass CLI runtime aliases through to PI in selectAgentHarnessDecision
When a model defines `agentRuntime.id` as a CLI runtime alias
(`claude-cli`, `google-gemini-cli`) or a configured `cliBackends` id, the
explicit-non-`auto` branch of `selectAgentHarnessDecision` previously
threw `MissingAgentHarnessError` because the alias has no agent harness
plugin counterpart. Model dispatch is unaffected (the CLI-runtime
short-circuit in `assertModelFallbackCandidateHarnessAvailable` runs
first), but every non-dispatch caller — delivery-mirror metadata
lookups, lane preflight, channel projection — surfaces the throw. On
Slack `[[reply_to:]]` deliveries the warning text gets substituted into
the assistant message synthesized as `provider: openclaw,
model: gateway-injected`, poisoning the thread.
Mirror the existing implicit-codex escape hatch in the same function:
when the runtime is a CLI alias (`isCliRuntimeAlias`) or a configured
CLI backend (`isCliProvider`), return PI with the new
`selectedReason: "cli_runtime_passthrough_pi"`. Actual CLI dispatch is
already routed by callers that consult model runtime policy, so PI here
is just a transcript-composition placeholder — non-CLI typos still
throw as before.
Refs #85582.
* fix(agents): validate CLI harness aliases by provider
* fix(agents): keep custom CLI harness ids fail-closed
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* docs(auth): document named OAuth profile logins
* feat(auth): support --profile-id in models auth login
* docs: note named model login profiles
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Restores WebChat image uploads to the media-understanding flow without one-turn model overrides.
- removes image-model override plumbing from the reply run
- stages WebChat images as MediaPaths for enrichment
- avoids replaying already-understood images to text-only reply models while preserving undescribed images
Co-authored-by: NianJiuZst <3235467914@qq.com>
* feat(anthropic): migrate 1M context from beta to GA
Anthropic has graduated the 1M context window from beta to GA.
This commit:
- Stops injecting the context-1m-2025-08-07 beta header when
context1m: true is configured
- Removes the OAuth token skip logic that was needed because
Anthropic previously rejected the context-1m beta with OAuth auth
(OAuth now supports 1M natively)
- Strips the legacy beta header from user-configured anthropicBeta
arrays to prevent sending a stale header
- Removes the now-unused isAnthropic1MModel helper,
ANTHROPIC_1M_MODEL_PREFIXES constant, and logger import from
the stream wrappers
The context1m config param continues to be respected for context
window sizing in context.ts — only the beta header injection is
removed.
Closes#45550 (Phase 1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(anthropic): migrate 1M context handling to GA
* fix(clownfish): address review for ghcrawl-156721-autonomous-smoke (1)
* fix(anthropic): restrict ga 1m context models
* docs(anthropic): align ga 1m context guidance
* fix(anthropic): normalize ga 1m model metadata
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(twitch): preserve newer message handler during cleanup
Fixes#83888.
`TwitchClientManager.onMessage` returns a cleanup closure that called
`messageHandlers.delete(key)` unconditionally. When a second onMessage()
for the same account replaced the handler, running the earlier cleanup
deleted the newer handler, leaving the account with no handler and
silently dropping all inbound messages.
Guard the delete with a referential check so the cleanup only removes
the handler it registered. Adds regression tests covering both the
stale-cleanup case (newer handler must survive) and the normal case
(current handler is still removed).
* fix(twitch): distinguish handler registrations
* fix(signal): avoid dangling test export name
* test(meeting-notes): use public sdk imports
* test(sdk): classify meeting-notes subpath
* fix(discord): keep channel entrypoint imports narrow
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Use the passive backend Gateway client for implicit local logs reads, and route Linux follow-mode local RPC failures to a bounded/redacted active systemd journal fallback instead of stale configured-file logs.
Fixes#83656Fixes#66841
Summary:
- The branch adds a config-aware tool auth helper, routes image/PDF/media generation preflight and list selection through it, threads `workspaceDir`, and adds focused regression tests plus a changelog entry.
- Reproducibility: yes. by source inspection. Current main gates affected media/PDF/generation preflight paths on env/profile auth while the runtime auth contract already accepts usable `models.providers.*.apiKey`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(tools): fall back to config apiKey in capability preflight
- PR branch already contained follow-up commit before automerge: fix(tools): honor config apiKey in media tool preflight
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8557…
Validation:
- ClawSweeper review passed for head b8c9242d77.
- Required merge gates passed before the squash merge.
Prepared head SHA: b8c9242d77
Review: https://github.com/openclaw/openclaw/pull/85570#issuecomment-4523770355
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Summary:
- Adds an optional archive-error callback for session transcript archiving, wires `/new` reset rotation to log previous-transcript archive failures, adds regression coverage, and updates the changelog.
- Reproducibility: yes. source-reproducible. Current main catches and ignores `archiveFileOnDisk` failures ins ... and the source PR proof exercises the same rename failure boundary with a real filesystem permission error.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 9d5f4c0c70.
- Required merge gates passed before the squash merge.
Prepared head SHA: 9d5f4c0c70
Review: https://github.com/openclaw/openclaw/pull/85586#issuecomment-4523917139
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* fix(qmd): normalize direct file collection paths
Port fix from PR #65212 to new package location.
When a QMD custom collection path config entry points directly to a file
instead of a directory, normalize into:
- path = parent directory
- pattern = exact filename
This ensures direct file targets are handled correctly regardless of any
user-supplied glob pattern.
Original commit: 3570aa55a7 (fix/flow-runs-legacy-migration)
* fix(qmd): escape direct file collection patterns
* fix(qmd): escape direct file collection masks
* fix(ui): run ui script through junction paths
* test(ui): make junction direct-execution test portable
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- This PR routes bare `openclaw` to classic onboarding for missing, empty, or metadata-only configs; keeps aut ... cs/changelog/tests; and narrows a Docker E2E boundary-check exception for an existing source-checkout lane.
- Reproducibility: not applicable. this is a feature/default-routing PR rather than a bug report. The branch p ... ill includes a fresh-state terminal run reaching `OpenClaw setup` and tests for the relevant config states.
Automerge notes:
- PR branch already contained follow-up commit before automerge: feat: start onboarding for fresh CLI installs
Validation:
- ClawSweeper review passed for head f4b2572f2e.
- Required merge gates passed before the squash merge.
Prepared head SHA: f4b2572f2e
Review: https://github.com/openclaw/openclaw/pull/85519#issuecomment-4522938004
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Prepack npm GitHub/git source update specs into temporary tarballs before the staged global npm install. Extends coverage to hosted GitHub HTTPS URLs without a `.git` suffix.
Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
The CONNECT handler pipes clientSocket and upstreamSocket together but
only registers an error handler on upstreamSocket. If the client
disconnects abruptly (ECONNRESET), the unhandled error event on
clientSocket causes the Node process to crash.
Add a clientSocket error handler that logs the event and destroys the
upstream socket. Also change clientSocket.end() to clientSocket.destroy()
in the upstream error handler since destroy() is more appropriate for
error cleanup of piped sockets.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(agents): handle parallel tool call deltas in openai-completions stream
The OpenAI completions streaming parser tracked only a single
`currentBlock` for tool calls and ignored `toolCall.index`. When the
API sends multiple `delta.tool_calls` entries (e.g., parallel tool
call scaffolding from kimi-for-coding), the parser created a new
block for every entry with a differing `id`, spawning phantom tool
calls with empty names and misrouting arguments.
Replace single-block tracking with Maps keyed by `index` and `id`,
matching the correct logic already present in the bundled
`@earendil-works/pi-ai` dependency. This ensures parallel and
interleaved tool call deltas accumulate to the correct block.
Fixes phantom "unknown" tool calls and empty arguments on
parameterized tools for providers that emit multiple tool_call
indices in streaming deltas.
* fix(agents): finalize tool-call blocks in place to keep maps live
ClawSweeper review [P1]: finishCurrentBlock() and finishAllToolCallBlocks()
were creating new block objects and replacing them in output.content,
but toolCallBlocksByIndex / toolCallBlocksById still pointed at the old
objects. Later deltas for those indices would mutate detached blocks,
causing argument loss and incorrect contentIndex in stream events.
Fix by finalizing arguments in place on the existing block objects.
Add regression test for parallel tool calls with split indices:
- two tool-call slots introduced in one chunk
- argument deltas arriving for each index in subsequent chunks
* fix(agents): keep byte counters out of emitted tool-call blocks
ClawSweeper review [P2]: partialArgsBytes was being stored directly on
the tool-call block objects pushed into output.content, exposing parser
scratch state to emitted stream events and final transcripts.
Replace the inline field with a WeakMap keyed by block object, keeping
byte tracking internal to the parser without polluting the public block
shape.
* refactor(agents): extract ToolCallBlock type for map declarations
ClawSweeper review [P1]: NonNullable<typeof currentBlock> at the map
declaration point was unreliable because currentBlock is initialized to
null and flow-narrowed. Define a local ToolCallBlock alias and use it
for toolCallBlocksByIndex, toolCallBlocksById, and toolCallBlockBytes
to give the maps a precise, stable type.
* fix(agents): iterate typed tool-call map in finishAllToolCallBlocks
ClawSweeper review [P1]: output.content elements are typed as
Record<string, unknown>, so block.partialArgs remained unknown even
after checking block.type === "toolCall". Latest CI failed strict
type checking at parseStreamingJson(block.partialArgs).
Fix by iterating toolCallBlocksByIndex.values() instead — the Map
values are already typed as ToolCallBlock, so partialArgs is known
to be a string and parseStreamingJson compiles cleanly.
- Restart the shared Codex app-server client when native server-side compaction times out.
- Retry native compaction once on the fresh app-server while preserving stale-thread cleanup only for `thread not found`.
- Add regression coverage and changelog entry for the preflight compaction recovery path.
Verification:
- `pnpm test extensions/codex/src/app-server/compact.test.ts`
- `env -u OPENCLAW_TESTBOX -u OPENCLAW_TESTBOX_REMOTE_RUN pnpm check:changed`
- `.agents/skills/autoreview/scripts/autoreview --mode local`
CI note: `build-artifacts` is red due inherited latest-main workflow/test drift, reproduced locally outside this PR diff and tracked in the pre-merge PR comment.
* fix(security): escape entry.id in HTML export to prevent attribute XSS
Apply escapeHtmlAttr to entry.id in renderEntry and renderCopyLinkButton
to prevent attribute injection via crafted entry IDs in HTML exports.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* chore: remove proof helper scripts from branch
ClawSweeper P2: committed proof scripts can provide false-positive
validation. Proof output is in the PR body instead.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
When the Slack adapter's startup auth.test call fails (bad token,
transient error, etc.), the bot user id silently stays empty for the
life of the process. The downstream explicit-bot mention check is
`botUserId && mentionedUserIds.includes(botUserId)`, which always
returns false when botUserId is empty. The result is that explicit
<@bot> mentions are silently classified as non-mentions with no log
trace explaining why.
Changes:
- provider.ts: stop swallowing auth.test failures; emit a warn log at
boot so the degraded state is observable. Empty user_id is treated
as a failure too.
- prepare.ts + subteam-mentions.ts: export the existing normalizeSlackId
helper and apply it to both sides of the explicit-bot equality check
(and to the mentioned-ids list). Real Slack ids are already uppercase,
so this is a no-op on healthy traffic, but it locks the invariant down
and removes the asymmetry between collected ids and the ctx bot id.
- prepare.test.ts: add two regression tests pinning the exact symptom:
positive case (botUserId set -> explicit_bot), negative case
(botUserId='' -> not explicit_bot, mention_source not explicit_bot).
🤖 AI-assisted.
Co-authored-by: in-liberty420 <in-liberty420@users.noreply.github.com>
Replace empty .catch(() => {}) on two failDelivery calls with
log.warn() so delivery queue mark-failed errors leave a diagnostic
trail instead of being silently discarded.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
`parseSlashCommandActionArgs` used a naive `startsWith` against the
configured slash prefix. When a skill name shares a prefix with a
built-in command (e.g. a skill named `config-check` vs the built-in
`/config`), the longer name was captured by the shorter built-in
handler and surfaced as an invalid action:
⚠️ /config is disabled. Set commands.config=true to enable.
Any skill whose name starts with a built-in command prefix
(`config-*`, `debug-*`, `models-*`, etc.) was unreachable via slash
invocation from any channel.
Fix: after the prefix match, require that the next character is
whitespace, a colon, or end-of-string. Otherwise the prefix
collided with a longer command name and we return `no-match` so the
longer handler — or the skill router — gets a chance to claim it.
Adds a regression test file `commands-slash-parse.test.ts` covering:
- `/config-check <args>` returns null (the reported case)
- `/configfoo` (no separator) returns null
- `/modelsy` returns null for the `/models` prefix
- `/config:json` still matches (colon is a valid boundary)
- `/config show enabled` still parses cleanly (whitespace boundary)
- empty body still returns the default action
Fixes#84572.
Co-authored-by: infracore <infracore@users.noreply.github.com>
* fix(tui): dismiss watchdog notice when response actually arrives
The streaming watchdog renders 'This response is taking longer than
expected. Send another message to continue.' after 30s without a chat
delta. If a delta or final then arrives — common for runs that are slow
but not stuck — the notice stays in the log alongside the recovered
response and contradicts what the user sees.
Track the notice by runId in the chat log via a new `addPendingSystem`
+ `dismissPendingSystem` pair (mirroring the existing pendingUsers
pattern) and dismiss it from `handleChatEvent` whenever any further chat
event for that run is processed. The watchdog's internal cleanup
(`activeChatRunId` reset, status idle, history reload) is unchanged.
Refs #67052, #69081 (closed). Prior attempt #69026 raised the threshold
and suppressed the notice entirely; this is the narrower fix that keeps
the warning useful for genuinely stuck runs.
* fix(tui): adapt pending notice to repeatable system entries
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The SIGTERM handler's fire-and-forget IIFE can reject if the graceful
drain or tunnel-teardown throws. Without a catch, this becomes an
unhandled promise rejection. Add .catch() that logs the error and
falls back to a hard stop request. Same treatment for SIGUSR1.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix: release cron runtime state after isolated runs
After an isolated cron/subagent run completes, the prepared context retains
references to the full in-memory session store and the registered agent run
context. Over many runs, these retained objects accumulate -- heap snapshots
showed ~2.0 GiB from ~113k copies of the skill prompt string flowing through
skillsSnapshot.prompt -> session entry -> cronSession.store -> cron run context.
Changes:
- Add disposeCronRunContext() to runCronIsolatedAgentTurn's finally block
- Calls clearAgentRunContext(sessionId) to remove the run context from the
global agent-events map
- Nulls cronSession.store to release the in-memory session registry copy
- Export clearAgentRunContext from run-execution.runtime.ts barrel
- The disposal is shallow O(1) -- no deep traversal, no hot-path disk writes
- Session persistence is unaffected (on-disk sessions.json is untouched)
The finally block guarantees cleanup on both success and error paths,
including timeout/abort scenarios.
Includes unit tests for clearAgentRunContext, store disposal, and
sweepStaleRunContexts.
* fix: remove duplicate storePath property in test fixture
* fix: remove unused clearAgentRunContext import from run-executor
* fix(cron): use initial sessionId for disposeCronRunContext in finally block
finalizeCronRun calls adoptCronRunSessionMetadata() which can rotate
sessionEntry.sessionId before the finally block runs. Capturing the
sessionId before the try block ensures clearAgentRunContext clears the
correct registered context instead of the potentially-rotated one.
Also removes unused imports (vi, beforeEach) from the runtime cleanup test.
* chore: trigger CI re-check for proof gate
* chore: retrigger CI proof gate
* test(cron): prove isolated run cleanup path
* fix(cron): keep shared run contexts active
* test(cron): avoid spreading typed-never fixture
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(exec): parse nested approval metadata in followups
(cherry picked from commit 10ff9b318e77cda3d65f40d59bbab0f4a3f59da8)
* docs(changelog): note exec approval nested-paren parser fix
* fix(exec): sanitize denied-reason literals in (...)-delimited approval messages
The exec-approval followup wire format is `Exec denied (gateway id=..., <deniedReason>): cmd`. The producer at `src/agents/bash-tools.exec-host-gateway.ts:606` was emitting `approval-timeout (allowlist-miss)`, which embedded literal parens inside the metadata segment and broke the metadata/body boundary for naive parsers. Switch the literal to a colon-separated form (`approval-timeout: allowlist-miss`) so the surrounding `(...)` delimiter stays unambiguous.
The Gateway node-event surface at `src/gateway/server-node-events.ts:734` interpolates an untrusted `obj.reason` into the same `Exec denied (node=..., <reason>)` format. Strip parens from that field before interpolation so a buggy or hostile node payload cannot smuggle metadata into the body slot.
The robust nested-paren parser already in `src/agents/exec-approval-result.ts` stays as defense in depth. Extend `exec-approval-result.test.ts` to cover the canonical colon-separated `deniedReason` and confirm `formatExecDeniedUserMessage` still maps it to the timeout copy.
* fix(exec): require gateway/node metadata source to reject spoofed approval wrappers
The exec-approval result parser previously accepted any string starting with
"Exec denied (..." or "Exec finished (..." as a structured approval wrapper.
Generic command stdout that happened to start with these tokens would be
classified as kind: "denied" or "finished", letting a tool's output spoof a
resolved-approval event in pi-embedded-subscribe.handlers.tools.ts:1173.
Reported by Aisle as CWE-841 (Improper Enforcement of Behavioral Workflow),
medium severity. The fix validates that the parenthesized metadata starts with
either "gateway id=" or "node=" — both prefixes are emitted by the legitimate
approval generators (bash-tools.exec-host-gateway.ts, bash-tools.exec-host-node.ts,
gateway/server-node-events.ts) and are unlikely to appear in arbitrary command
output. Inputs that fail this check now return kind: "other", which all callers
already handle as a no-op.
* fix(exec): keep sandbox_blocked classification for raw exec-denied messages
After the spoof-guard tightening of parseExecApprovalResultText, inputs that
lack a gateway/node-sourced metadata prefix (such as the synthetic
"exec denied (allowlist-miss):" string used in classifier tests) no longer
return kind: "denied" and therefore no longer trigger formatExecDeniedUserMessage,
so isSandboxBlockedErrorMessage stopped recognising them.
Add a direct \bexec denied\s*\( alternative to SANDBOX_BLOCKED_RE so the
classifier still treats any raw "exec denied (" prefix as sandbox-blocked,
independent of whether the parser accepts the surrounding wrapper. This keeps
classifyProviderRuntimeFailureKind's existing behavior for unstructured exec-
denied messages.
Add documentation for the dynamicAgentCreation feature used to create
isolated agents per Feishu/Lark user. Covers:
- dynamicAgentCreation configuration fields (enabled, workspaceTemplate,
agentDirTemplate, maxAgents)
- Automatic agent/workspace creation flow
- Session isolation with dmScope
- Template variables ({agentId}, {userId})
- Verification steps and example deployment
Refs: feature available since OpenClaw 2026.4.25+
Co-authored-by: li <li@lideMac-mini.local>
* docs(channels/slack,telegram): document ackReactionScope and its DM-excluding default
The Slack and Telegram channel docs documented `ackReaction` but not
`ackReactionScope`, even though the scope (defaulting to
`group-mentions`) silently excludes DMs. People who set `ackReaction`
and expect to see an emoji on DMs are surprised when nothing fires.
This adds:
- The resolution order for `ackReactionScope` (per-account → channel →
`messages.ackReactionScope` → default `group-mentions`).
- The full list of scope values (`all`, `direct`, `group-all`,
`group-mentions`, `off`/`none`).
- A Note callout flagging that the default does not react in DMs and
that `messages.ackReactionScope` requires a gateway restart to take
effect.
- A short JSON example for the common case (`ackReactionScope: "all"`).
Mirrors the structure already used in `docs/channels/matrix.md`.
Found while configuring Slack DMs to show `👀` ack reactions and
discovering that the docs covered the emoji but not the scope gate. AI-assisted.
* fixup: scope is messages-only for Slack & Telegram (not per-account)
Reviewer correctly noted that the Slack and Telegram runtimes only read
`cfg.messages?.ackReactionScope` and the per-account/per-channel
`ackReactionScope` keys don't exist in those schemas (only Discord and
Matrix support them). Drop the misleading resolution-order bullets and
document `messages.ackReactionScope` only.
Verified against:
- extensions/slack/src/monitor/provider.ts:243
- extensions/telegram/src/bot-core.ts:262
- src/config/types.slack.ts (no ackReactionScope in account schema)
- src/config/types.telegram.ts (no ackReactionScope in account schema)
Keeps the DM-default gotcha, the full enum, and the gateway-restart note,
which were the original value of the PR.
---------
Co-authored-by: Dr. Claw <drclaw-iq@users.noreply.github.com>
Recreated from #85108 because the original branch could not be updated by maintainers.
Preserves current-main pnpm install hardening while switching workflow pnpm setup to packageManager, and adds exact version-scoped release-age exclusions for already-locked packages that pnpm 11.2.2 audits during install.
Co-authored-by: Altay <altay@hey.com>
Fixes#5369.
Preserve fresh session-store state when the agent handler observes a stale cached session entry, including model/provider overrides, send policy, delivery metadata, lifecycle timestamps, and fresh session rotations.
Co-authored-by: CodeReclaimers <github@codereclaimers.com>
Fixes the embedded attempt session write-lock watchdog so the fallback max hold time follows the resolved compaction timeout plus the existing lock grace window, instead of inheriting the full run timeout.
Adds regression coverage for the helper and settled-compaction lock lifecycle, plus a changelog entry thanking @luoyanglang.
Verification:
- `pnpm test src/agents/session-write-lock.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts src/agents/pi-embedded-runner/run/attempt.session-lock.test.ts`
- `pnpm check:changed` via Blacksmith Testbox `tbx_01ks8b6vn8se5cg1dfn3te3g47` / https://github.com/openclaw/openclaw/actions/runs/26301988670
- Autoreview clean: `/Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview --mode branch --base origin/main`
- PR CI green on `79e8c5f1a637981d263c0268bf5666967ff4e778`: https://github.com/openclaw/openclaw/actions/runs/26302152844 and https://github.com/openclaw/openclaw/actions/runs/26302152798
Co-authored-by: luoyanglang <hanwanlonga@gmail.com>
Summary:
- Document that MEDIA directives must be plain-text line-start metadata.
Verification:
- Source check: src/media/parse.ts only recognizes lines whose trimmed start begins with MEDIA: and skips fenced code blocks.
- PR CI: check-docs succeeded.
Summary:
- The PR moves gateway provider auth-state prewarm into cancelable post-ready gateway lifetime work, uses current runtime config for delayed warms, and adds related gateway/provider-auth tests plus a changelog entry.
- Reproducibility: no. high-confidence runtime reproduction was run in this review. Source inspection shows th ... th on current main, and the source PR supplies live after-fix proof for the focused startup-ordering slice.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(gateway): defer provider auth prewarm after startup
Validation:
- ClawSweeper review passed for head 31ea4288e3.
- Required merge gates passed before the squash merge.
Prepared head SHA: 31ea4288e3
Review: https://github.com/openclaw/openclaw/pull/85369#issuecomment-4519123491
Co-authored-by: Bob <dutifulbob@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Summary:
- The PR teaches `openclaw devices approve <requestId>` to approve a compatible same-device replacement request during local fallback and adds focused CLI, infra, and changelog coverage.
- Reproducibility: yes. Source inspection shows current main rejects the gateway's replacement requestId as a ... adds focused infra and CLI tests for the churn path; I did not run tests because this review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs: note device approval recovery
Validation:
- ClawSweeper review passed for head 1d2f2e9b2f.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1d2f2e9b2f
Review: https://github.com/openclaw/openclaw/pull/85342#issuecomment-4518449317
Co-authored-by: masonxhuang <masonxhuang@tencent.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
normalizeAllowedModelRef() and the resolved override ref interpolated
${provider}/${model} after normalizeModelRef(), so a provider-qualified
model id like openrouter/gpt-5.4-mini surfaced as
openrouter/openrouter/gpt-5.4-mini in the allowlist set and policy
denial message, masking the actionable model ref.
Route both sites through modelKey() (src/agents/model-ref-shared.ts)
so the provider segment is collapsed when the model id already starts
with it. Add regression tests covering allowlist hit and denial paths
for the OpenRouter shape.
Fixes#84887
* fix(gateway): include openclaw bin in service PATH
* fix(doctor): accept expected service PATH
* docs(changelog): mention managed service PATH bin fix
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary:
- Honor per-model api/baseUrl overrides during custom provider auth hook lookup and transport selection.
- Keep models-add metadata safeguards intact and add focused auth/model resolver regression coverage.
- Add maintainer changelog credit for @huveewomg.
Verification:
- git diff --check
- GitHub CI green on 277629e992
- GitHub CodeQL green on 277629e992
- GitHub CodeQL Critical Quality green on 277629e992
- GitHub Real behavior proof green on 277629e992
- Local focused Vitest was stopped after 8 minutes on a busy host without producing a result; PR CI supplied the final proof.
Co-authored-by: huveewomg <wongrenthou1265@gmail.com>
* fix(gateway): eager-load lifecycle runtime to survive in-place upgrades
After a package-swap update (e.g. via update.run), dist/ chunk hashes
rotate while the gateway is still running. The SIGUSR1 listener's first
dynamic import of the lifecycle runtime module then throws
ERR_MODULE_NOT_FOUND inside its async IIFE, silently rejects, and leaves
restart.ts's emittedRestartToken permanently unconsumed. From that point
every scheduleGatewaySigusr1Restart() — including the one update.run
schedules for itself — returns { coalesced: true } without scheduling
anything, and the gateway never restarts until manually kickstarted.
Fix:
1. Eagerly resolve the lifecycle runtime module as the first statement
of runGatewayLoop, before any signal listener is installed. lifecycle.runtime
is a 36-line re-export hub, so loading it once pulls the entire restart
/ respawn / queue / sentinel / handoff graph into memory, immune to
later disk rotation. If the module is missing at startup, fail fast
with a loud error so the supervisor can recover instead of running
half-broken.
2. Defense in depth: catch SIGUSR1 IIFE rejections and call
markGatewaySigusr1RestartHandled() via the eagerly captured reference,
so a transient listener failure doesn't permanently stick the restart
token.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(changelog): mention lifecycle restart eager load
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary:
- The branch replaces the Crabbox wrapper's hardcoded provider allow-list with help-output parsing, preserves current aliases and a known help omission, adds wrapper tests, and updates the changelog.
- Reproducibility: yes. source-reproducible: current main only rejects selected providers that are already in ... rovider names can bypass wrapper validation. I did not run the PR branch because this review was read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: refactor(crabbox): parse provider list from binary help instead of ha…
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8530…
Validation:
- ClawSweeper review passed for head c99388d92a.
- Required merge gates passed before the squash merge.
Prepared head SHA: c99388d92a
Review: https://github.com/openclaw/openclaw/pull/85302#issuecomment-4517730136
Co-authored-by: masonxhuang <masonxhuang@tencent.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Limit sub-agent bootstrap context to AGENTS.md and TOOLS.md without adding a new config surface. Preserve the existing cron minimal bootstrap behavior.
Co-authored-by: Eva (agent) <eva+agent-78055@100yen.org>
Close child ACP runtimes during parent reset/delete through a shared direct-child session lookup, covering spawnedBy and parentSessionKey lineage across combined agent stores.
Also adds focused regression coverage for direct child discovery, non-ACP/unrelated negatives, reset cleanup, delete cleanup, cross-store children, and concurrent stuck-child cleanup.
Co-authored-by: openperf <16864032@qq.com>
Summary:
- The branch adds a Google provider thinking-policy resolver and opt-in profile flag, updates shared thinking validation and cron/proof-policy tests, and adjusts ClawSweeper proof parsing.
- Reproducibility: yes. source-reproducible: current main applies the generic off-only profile before provider ... figured thinking through that resolver. I did not execute a live systemd cron run in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: preserve Google Gemini 3 cron thinking
Validation:
- ClawSweeper review passed for head a6cd2e826e.
- Required merge gates passed before the squash merge.
Prepared head SHA: a6cd2e826e
Review: https://github.com/openclaw/openclaw/pull/85300#issuecomment-4517662575
Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Keep derived plugin metadata snapshots out of the process memo/current snapshot cache so newly added plugins under derived discovery paths are found without restart.
The deriveIdHint function already strips -provider from unscoped
package names (@openclaw/anthropic-provider -> anthropic) but does
not strip -plugin (@openclaw/xai-plugin -> xai-plugin instead of
xai). This causes ~30 spurious 'plugin id mismatch' warnings on
gateway startup for built-in plugins whose package names end in
-plugin.
Closes#85048
* fix(gemini): strip sub-second precision from web_search time_range_filter
Gemini's google_search.time_range_filter rejects any non-zero fractional
seconds with "[FIELD_INVALID] Granularity of nano is not supported", even
though the underlying google.protobuf.Timestamp type accepts 0/3/6/9
fractional digits per its public spec. The grounding endpoint enforces a
stricter rule than the underlying type.
Date.prototype.toISOString() always emits millisecond precision, so every
freshness call (and any date_after/date_before call hitting the "now"
fallback for endTime) failed with the above 400 after #66498's fix shipped
in 2026.5.19.
Introduce toGeminiTimeRangeTimestamp() which strips the fractional-second
component before serializing, and route all four timeRangeFilter timestamp
sites through it. isoDateExclusiveEnd happens to produce all-zero
fractional today (so Gemini accepts it), but routing it through the helper
keeps the contract uniform and resilient to future changes.
Why this slipped past the original CI: the existing freshness test used
vi.setSystemTime(new Date("2026-04-15T12:00:00Z")), which always
serializes back as ".000Z" — the one fractional form Gemini happens to
accept. Wall-clock new Date() in production always has non-zero ms. The
new test uses setSystemTime(new Date("2026-04-15T12:00:00.123Z")) to
exercise the realistic case.
Verified empirically against the live Gemini REST API:
".123Z" → 400 "Granularity of nano is not supported"
".000Z" → grounded content (the one fractional form accepted)
"Z" → grounded content
Fixes#85061.
* test(gemini): use realistic non-zero ms in existing freshness test
The original test set the fake clock to a moment with zero fractional
seconds, so toISOString() produced ".000Z" — the one fractional form
Gemini's google_search.time_range_filter happens to accept. Wall-clock
new Date() in production produces non-zero ms, which Gemini rejects.
Bumping the fake time to .123Z makes the existing test exercise the
realistic case alongside the dedicated regression test.
---------
Co-authored-by: Noah R <Noerr@users.noreply.github.com>
Summary:
- The PR changes generated-media duplicate guards, completion delivery fallback behavior, transcript write-lock reuse, task-registry fresh owner reads, docs, changelog, and regression coverage.
- Reproducibility: yes. with source and artifact evidence rather than a local rerun: current main completes me ... e task and one successful video task after the patch. I did not run tests because this review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: dedupe media completion delivery
- PR branch already contained follow-up commit before automerge: fix: avoid music provider lookup for explicit models
- PR branch already contained follow-up commit before automerge: fix: narrow detached media task handles
- PR branch already contained follow-up commit before automerge: fix: close media completion review gaps
- PR branch already contained follow-up commit before automerge: fix: tolerate media delivery mirrors during session lock
- PR branch already contained follow-up commit before automerge: Fix media completion duplicate delivery
Validation:
- ClawSweeper review passed for head f83e3bf143.
- Required merge gates passed before the squash merge.
Prepared head SHA: f83e3bf143
Review: https://github.com/openclaw/openclaw/pull/84006#issuecomment-4484835103
Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Surface local post-challenge connect assembly failures immediately instead of waiting for the Gateway CLI wrapper timeout.\n\nCo-authored-by: samzong <samzong.lu@gmail.com>
Summary:
- The branch passes runtime config into the model config write helper, updates `openclaw models set` to resolve aliases source-first then runtime-fallback, and adds regression tests plus a changelog entry.
- Reproducibility: yes. I did not execute the CLI in this read-only review, but the current-main source path a ... ing against source config while runtime defaults can be the only place the displayed `sonnet` alias exists.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(models): preserve authored aliases for set
- PR branch already contained follow-up commit before automerge: fix(models): resolve set aliases from runtime config [AI-assisted]
Validation:
- ClawSweeper review passed for head 29138ac5d0.
- Required merge gates passed before the squash merge.
Prepared head SHA: 29138ac5d0
Review: https://github.com/openclaw/openclaw/pull/83262#issuecomment-4472495568
Co-authored-by: JARVIS-Glasses <284122573+JARVIS-Glasses@users.noreply.github.com>
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
The watcher fired constantly because the gateway itself rewrites
auth-profiles.json frequently (cooldown ticks, usage stats, OAuth
refresh, markAuthProfileFailure). Each self-write triggered chokidar
which cleared the prepared auth map and scheduled an ~8 s rewarm,
a feedback loop that defeated the caching the rest of the PR added.
Drop the watcher entirely. Self-heal still covers the stale-TRUE
direction via the markAuthProfileFailure hook. Stale-FALSE (user adds
auth externally and the gateway hasn't observed any request through
that profile yet) reverts to the pre-PR behavior: reload config or
restart gateway to pick it up. Known limitation.
Summary:
- The PR rejects Codex app-server command overrides that embed Node/package-manager inline arguments, adds matching doctor diagnostics, regression tests, and a changelog entry.
- Reproducibility: yes. for the scoped malformed override path: current main passes the combined command strin ... ix resolver/doctor live output. I did not establish a live Windows npm-global managed-startup reproduction.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Validate Codex app-server command overrides
Validation:
- ClawSweeper review passed for head 966bcd6617.
- Required merge gates passed before the squash merge.
Prepared head SHA: 966bcd6617
Review: https://github.com/openclaw/openclaw/pull/84417#issuecomment-4494295224
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Remove the chat picker recency/current-agent filters while preserving the bounded configured-agent refresh, and add the changelog credit for @amknight.
Summary:
- The PR removes the auto-reply compaction-failure session reset hook, adds preserved-session recovery guidance for overflow/compaction failure paths, and updates focused tests, docs, and the changelog.
- Reproducibility: yes. at source level with high confidence. Current main routes both embedded overflow paylo ... resetSessionAfterCompactionFailure, and the PR body includes before/after terminal proof of those branches.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(auto-reply): drop dead compaction reset hook
- PR branch already contained follow-up commit before automerge: fix(auto-reply): preserve sessions after compaction failures
Validation:
- ClawSweeper review passed for head 193d3c0fdd.
- Required merge gates passed before the squash merge.
Prepared head SHA: 193d3c0fdd
Review: https://github.com/openclaw/openclaw/pull/70479#issuecomment-4325128777
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Addresses three ClawSweeper findings on the fs-watcher commit:
- [P1] auth-profile watcher now handles chokidar 'error' events (logs +
closes once) mirroring the gateway config-reload pattern. Without
this, an unhandled error from chokidar can crash the gateway.
- [P2] auth-profile watcher handle is pushed into postReadySidecars so
stopPostReadySidecarsAfterCloseStarted closes it on gateway shutdown.
- [P2] auth-failure and file-change invalidation paths now schedule a
background rewarm (with a 'reason=' log line). Without this, the next
/models call after an invalidation paid the slow per-provider path
until the next reload. The warmer's existing generation counter
handles concurrent rewarms safely.
Adds a chokidar watcher on every configured agent's auth-profiles.json.
Any change fires clearCurrentProviderAuthState so the next model-listing
call recomputes against the on-disk auth state. Closes the stale-FALSE
direction (user adds auth via codex login, hand-edit, etc.) that the
auth-failure hook can't catch on its own.
When markAuthProfileFailure observes an auth failure at request time
(token rotated, OAuth revoke, etc.), fire a hook that clears the
prepared provider-auth map so the next model-listing call recomputes
against the real auth state. Single mutable hook slot wired up at
gateway startup; no TTL or polling.
Addresses ClawSweeper's P1 freshness finding on #85125 without
reintroducing the TTL.
Summary:
- The PR changes shared, Feishu, Mattermost, Microsoft Teams, and WhatsApp inbound debounce predicates so bare abort text bypasses debounce, then adds focused tests and a changelog entry.
- Reproducibility: yes. source-level. Current main sends bare `stop`, `abort`, and `wait` through a `hasContro ... ()` debounce gate, while the existing abort-aware detector and trigger set already recognize those phrases.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(channels): bypass debounce for bare abort triggers [AI-assisted]
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8334…
Validation:
- ClawSweeper review passed for head c96bf84270.
- Required merge gates passed before the squash merge.
Prepared head SHA: c96bf84270
Review: https://github.com/openclaw/openclaw/pull/83348#issuecomment-4473176095
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch adds an abort-aware dispatcher-idle wait after successful same-channel and direct ACP block replies, plus regression tests and a changelog entry.
- Reproducibility: yes. Current main source shows the same-channel block callback queues dispatcher delivery w ... spatcher idle, and the PR body supplies before/after diagnostic output for the tool-start ordering failure.
Automerge notes:
- PR branch already contained follow-up commit before automerge: [AI-assisted] fix(reply): wait for block replies before tools
Validation:
- ClawSweeper review passed for head 32576209a2.
- Required merge gates passed before the squash merge.
Prepared head SHA: 32576209a2
Review: https://github.com/openclaw/openclaw/pull/83722#issuecomment-4480639845
Co-authored-by: JARVIS-Glasses <284122573+JARVIS-Glasses@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Harden the Codex app-server native execution bridge for OpenClaw sandboxed runs. The change keeps core sandbox policy in OpenClaw while exposing the process, filesystem, and HTTP relay behavior Codex needs inside a scoped exec server.
The large exec-server/test files were split into focused modules before landing, and the PR was rebased onto current main with focused tests, Testbox changed checks, CI, and Codex autoreview green.
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
Summary:
- The PR adds shared blocked-liveness normalization, applies it to agent.wait, gateway dedupe, subagent registry, and announcement paths, and adds regression tests plus a changelog entry.
- Reproducibility: yes. from source inspection: current main accepts blocked lifecycle/wait metadata as ok thr ... gateway wait and registry completion paths. I did not run a live provider overflow in this read-only pass.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(agents): normalize blocked wait completions
- PR branch already contained follow-up commit before automerge: fix(agents): surface blocked subagent completions
Validation:
- ClawSweeper review passed for head 224785c8a6.
- Required merge gates passed before the squash merge.
Prepared head SHA: 224785c8a6
Review: https://github.com/openclaw/openclaw/pull/80886#issuecomment-4427552621
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Adds installRecords to PluginLoadOptions and PluginRuntimeLoadContext so
callers that already hold a PluginMetadataSnapshot can pass the snapshot's
in-memory records instead of forcing each downstream loader to re-read
installs.json. resolvePluginRuntimeLoadContext extracts the records from
the snapshot via extractPluginInstallRecordsFromInstalledPluginIndex,
buildPluginRuntimeLoadOptionsFromValues forwards them, and the setup +
runtime provider load paths in providers.runtime.ts pass them through
from params.pluginMetadataSnapshot. resolvePluginLoadCacheContext uses
the threaded records (falling back to the sync read) and
loader-provenance now uses params.installRecords ?? sync-read instead of
always reading and overlaying.
Log structured details when Discord persistent component registry state falls back after a store failure.
- Format Error name, message, stack, and cause metadata at the Discord registry warning call site.
- Forward plugin runtime logger metadata to the underlying child logger.
- Add focused regression coverage for the Discord fallback warning and runtime logging adapter.
- Add changelog credit for @100menotu001.
Fixes#84185.
Co-authored-by: OpenClaw Contributor <100menotu001@users.noreply.github.com>
Co-authored-by: Craig <froelich@craigs.mac.studio.froho>
Summary:
- The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog.
- Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules
- PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry
- PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l…
- PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint
Validation:
- ClawSweeper review passed for head 416a8a2e77.
- Required merge gates passed before the squash merge.
Prepared head SHA: 416a8a2e77
Review: https://github.com/openclaw/openclaw/pull/76974#issuecomment-4367336485
Co-authored-by: BSG2000 <github@hsu.hamburg>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com>
Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de>
Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Preserve `reusable` for portable message presentation buttons and carry it through Discord component registration so repeatable callbacks stay available after a successful interaction.
Also keeps `reusable` through legacy presentation-to-interactive conversion and documents the user-visible change in the changelog.
Verification:
- `pnpm test src/interactive/payload.test.ts extensions/discord/src/shared-interactive.test.ts extensions/discord/src/components.test.ts -- --reporter=verbose`
- `git diff --check`
- `AUTOREVIEW_AUTO_TESTS=0 .agents/skills/autoreview/scripts/autoreview --mode local`
- PR CI at `52f25221b3e01f3255d8df37df73d0357ab7410b`: all completed checks green/skipped/neutral except pending CodeQL `Security High (mcp-process-tool-boundary)` at time auto-merge was armed.
Co-authored-by: OpenClaw Contributor <100menotu001@users.noreply.github.com>
Summary:
- The branch teaches Ollama discovery to use resolved `discoveryApiKey` values for non-local cloud providers, preserves local marker auth, and adds focused provider-discovery regressions plus a changelog entry.
- Reproducibility: yes. from source inspection: current main can return the `OLLAMA_API_KEY` marker instead of ... ential for documented Ollama Cloud config. I did not run executable tests because this review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: ci: allowlist qa lab fixtures
- PR branch already contained follow-up commit before automerge: Fix Ollama cloud API key discovery
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8503…
Validation:
- ClawSweeper review passed for head cb6b658819.
- Required merge gates passed before the squash merge.
Prepared head SHA: cb6b658819
Review: https://github.com/openclaw/openclaw/pull/85091#issuecomment-4512647237
Co-authored-by: Anup Sharma <anupnewsmail@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
The auto-migration introduced in #83312 only fires when a credential is loaded
via a path that reads its sidecar tokens. The OAuth refresh manager's internal
loader does (so direct CLI inference works and self-heals on first refresh).
The embedded runner's secrets-runtime loaders did not:
- loadAuthProfileStoreForSecretsRuntime
- loadAuthProfileStoreWithoutExternalProfiles
- ensureAuthProfileStoreWithoutExternalProfiles
All three opted out of sidecar resolution. So for an upgraded user with a
legacy oauthRef-backed openai-codex profile, the credential loaded with no
access/refresh material, evaluateStoredCredentialEligibility marked it
ineligible, resolveAuthProfileOrder filtered it out, and resolveApiKeyForProvider
threw "No API key found for provider 'openai-codex'" before the OAuth manager
(and its migration path) was ever consulted. CLI worked, Telegram/cron/embedded
turns broke — only doctor-or-bust would fix it.
Flip the three embedded loaders to default resolveLegacyOAuthSidecars to true
(matching loadStoredOAuthRefreshStore). The existing #83312 refresh-and-rewrite
then fires on the first embedded turn for these users and persists tokens
inline, removing the legacy sidecar from disk on the next doctor pass.
Cherry-picked and squashed from PR #84752 (commits 85f36e8d2b and
4624e34c06). Comments noting local-fork bookkeeping stripped per repo policy.
Co-authored-by: Will <totalsolutionspm@gmail.com>
P1 (auth-profile logout): invalidateModelAuthStatusCache now also clears
the prepared provider-auth map, and the models.auth.logout handler fires
a rewarm against the current config. Without this, removing a provider's
auth profiles left the warmed 'true' answer in the map until restart,
so /models and pickers kept advertising the removed provider.
P1 (plugin-reload ordering): the previous version fired the rewarm
inline with the clear, before plan.reloadPlugins() ran. The warmer
reads plugin metadata and synthetic-auth hooks, so it published the
pre-reload runtime's answers. Moved the rewarm to fire after the
plugin-reload block completes, so it reads the new plugin runtime.
The early clear still happens upfront so callers don't keep seeing the
pre-reload answer during the reload window.
ClawSweeper P1 + P2 findings on the prior review-fix commit.
- [P1] hasAuthForModelProvider now also checks workspaceDir against the
warm's snapshot value. The warmer uses resolveDefaultAgentWorkspaceDir,
but per-agent picker calls (buildModelsProviderData →
resolveVisibleModelCatalog → createProviderAuthChecker) thread an
agent-specific workspaceDir, and provider env/synthetic-auth
resolution depends on it. Without this check the picker for agent B
would silently reuse agent A's warmed answer.
- [P1] warmCurrentProviderAuthState now claims a generation counter at
the start of its work and only publishes the new state if the
generation hasn't been bumped (by a concurrent clear or another
warm). Closes the race where a slow startup warm could overwrite a
newer reload-driven rewarm with stale data.
- [P2] Reload handler now also clears and rewarms the prepared map
when plugins.* config paths change. Provider auth can come from
plugin env vars and plugin synthetic-auth wiring, so plugin hot
reloads must invalidate the auth state too — not just model config
paths.
Test: new case asserting a non-default workspaceDir caller bypasses the
prepared map and falls through to compute.
Two fixes flagged by ClawSweeper.
P1 — hasAuthForModelProvider now only short-circuits via the prepared
map when the caller's scope matches the warmer's (broad discovery, no
agentDir/env/store override). Read-only gateway model lists pass
runtimeAuthDiscovery: false, which the visibility helper maps to
discoverExternalCliAuth: false and allowPluginSyntheticAuth: false; the
prepared broad answer was previously masking that narrower intent. Now
those callers fall through to compute the narrow answer.
P2 — server-reload-handlers now also schedules a rewarm right after
clearing the prepared state on model-config reload, so long-lived
gateways don't regress to per-call discovery between reload and the
next restart.
Test: extends model-provider-auth.test.ts with a scope-narrowing case
asserting the prepared answer is bypassed when the caller passes
discoverExternalCliAuth: false / allowPluginSyntheticAuth: false.
Asserts hasAuthForModelProvider returns the warmed answer for providers
in the prepared map and skips the compute path, and that
clearCurrentProviderAuthState restores fall-through to compute.
Eliminates the per-call auth-filter loop that every /models invocation
(Discord/Telegram pickers, CLI, status commands) was paying — 30 unique
providers × ~600 ms each of plugin-runtime / external-CLI / auth-profile
discovery, done fresh on every call (~20 s per call).
warmCurrentProviderAuthState builds a provider->boolean map once at
gateway startup against a single AuthProfileStore scoped to every
candidate provider, and hasAuthForModelProvider consults the prepared
map first and short-circuits. The map is invalidated on config reload
alongside resetModelCatalogCache so the next read after a relevant
config change rewarms.
Per /models: ~20,569 ms → ~5 ms (~4,100×).
One-time startup warm cost: ~49 s (cold catalog + auth sweep), logged
via gateway log.info on completion.
knip's deadcode-unused-files check ignores fixtures matching **/*.fixture.ts
(dot before "fixture"). The codex lifecycle fixtures landed in bbf3eec786
as auth-profile-fixture.ts and codex-plugin-fixture.ts (hyphen), so knip
flagged them as unexpected unused files and CI's check-dependencies job
has been failing on main since then. Rename to auth-profile.fixture.ts
and codex-plugin.fixture.ts and update the lifecycle test, the fixture
cross-import, and the six qa/scenarios markdown files that reference
them by path and qaImport specifier.
Summary:
- The branch scopes config-time Google Gemini preview model normalization to Google providers or nested `google/` proxy suffixes, adds model-picker regression coverage, and adds a changelog entry.
- Reproducibility: yes. by source inspection. Current main sends every provider suffix through the Google prev ... i-3-flash` deterministically becomes `litellm/gemini-3-flash-preview`; I did not run a live cron preflight.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(config): scope Google preview model normalization to Google provi…
- PR branch already contained follow-up commit before automerge: fix#84745: scope Google preview model normalization to Google provid…
- PR branch already contained follow-up commit before automerge: fix#84745: preserve proxy Google model normalization
Validation:
- ClawSweeper review passed for head c59163c809.
- Required merge gates passed before the squash merge.
Prepared head SHA: c59163c809
Review: https://github.com/openclaw/openclaw/pull/84762#issuecomment-4504169062
Co-authored-by: zhang-guiping <zhang.guiping@xydigit.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: 张贵萍0668001030 <zhang.guiping@xydigit.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
OAuth credentials that loaded without their sidecar material (no access, no
refresh) would still enter the refresh path inside the per-profile lock,
where the adapter call is bounded by OAUTH_REFRESH_CALL_TIMEOUT_MS (120s).
That made the eventual "No API key found for provider" surface to the user
only after a long stall, even though the resolver had no usable material to
attempt with.
Short-circuit doRefreshOAuthTokenWithLock to return null when there is no
refresh token to use, after the in-lock main-store adoption and external
bootstrap-credential checks have already had a chance to recover.
Thanks @romneyda.
Summary:
- The PR wraps the async JSON file readers in `src/infra/json-files.ts` with bounded retries for fs-safe `File changed during read` races, adds regression tests, and adds a changelog entry.
- Reproducibility: yes. Source inspection shows fs-safe throws `File changed during read`, current main re-exp ... R proof includes before/after gateway logs; I did not run a new live race harness in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(json): preserve strict reader types (Promise<T> for readJson/read…
- PR branch already contained follow-up commit before automerge: test(json): add retry-success and retry-exhaustion coverage
- PR branch already contained follow-up commit before automerge: fix(json): resolve lint warnings (prefer-exponentiation-operator, cur…
- PR branch already contained follow-up commit before automerge: fix(json): retry on transient File changed during read race condition
Validation:
- ClawSweeper review passed for head 00602a1c03.
- Required merge gates passed before the squash merge.
Prepared head SHA: 00602a1c03
Review: https://github.com/openclaw/openclaw/pull/85029#issuecomment-4510494668
Co-authored-by: samson1357924 <98934496+samson1357924@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This replacement PR adds inbound delivery diagnostic events, gateway status counters and warnings, transport ... ut, Prometheus/OpenTelemetry metrics, docs, changelog, and regression coverage for gateway delivery health.
- Reproducibility: no. high-confidence live reproduction of the original Feishu failure was run here. Source i ... ch/turn telemetry, and the source PR supplies after-fix live output for the connected WebChat gateway path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(types): restore PR conflict resolution type checks
Validation:
- ClawSweeper review passed for head 6ffe08a9c7.
- Required merge gates passed before the squash merge.
Prepared head SHA: 6ffe08a9c7
Review: https://github.com/openclaw/openclaw/pull/85016#issuecomment-4510224436
Co-authored-by: Andi Liao <liaoandi95@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds Docker/OrbStack host aliases to Ollama local-auth classification, keeps those aliases out of loopback-only discovery suppression, adds regression tests, and updates the changelog.
- Reproducibility: yes. The linked report gives a concrete v2026.5.19 config and error, and current main source shows host.orb.internal is not classified as local for ollama-local marker auth.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ollama): allow Orb host local auth
Validation:
- ClawSweeper review passed for head cb82dcf522.
- Required merge gates passed before the squash merge.
Prepared head SHA: cb82dcf522
Review: https://github.com/openclaw/openclaw/pull/84999#issuecomment-4509786332
Co-authored-by: Bob <dutifulbob@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Summary:
- The branch clears WebChat local run and stream state when terminal session reconciliation completes the acti ... session events, adjusts deferred history/queue flushing, adds regression tests, and updates the changelog.
- Reproducibility: yes. with high confidence from source inspection and PR evidence. Current main can apply a ... PR body, recording, and regression shape show the stale WebChat typing state being cleared by this branch.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: harden webchat session run reconciliation
Validation:
- ClawSweeper review passed for head 89cca8dd01.
- Required merge gates passed before the squash merge.
Prepared head SHA: 89cca8dd01
Review: https://github.com/openclaw/openclaw/pull/84565#issuecomment-4498262223
Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: jesse-merhi
Add the missing changelog entry for the landed Web Push VAPID subject fix and refresh the config docs baseline hash to match the Node 24 check environment.
Summary:
- The PR preserves native Ollama tool-call IDs through ingest and replay, opts native Ollama out of strict replay ID sanitization, and adds focused regression tests plus a changelog entry.
- Reproducibility: yes. Current main drops native Ollama tool-call IDs on ingest and replay and applies strict ... PR discussion includes a maintainer-side before/after probe that reproduced the source-level failure path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ollama): keep native tool ids through replay
Validation:
- ClawSweeper review passed for head bb9fef7d4c.
- Required merge gates passed before the squash merge.
Prepared head SHA: bb9fef7d4c
Review: https://github.com/openclaw/openclaw/pull/84855#issuecomment-4505423891
Co-authored-by: IWhatsskill <whatsskilll@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
* fix(config): append numeric bound hints to ceiling/floor validation errors
When a config value exceeds a schema-enforced ceiling or falls below a
floor, the error message now includes the constraint explicitly:
- Inclusive: `(maximum: 20)` / `(minimum: 0)`
- Exclusive: `(must be less than 5)` / `(must be greater than 0)`
This matches the clarity that enum/union rejections already get via
`(allowed: …)` hints, and avoids the misleading "minimum: 0" wording
that previous attempts produced for `.positive()` / `.gt(0)` rejections.
Only numeric-origin `too_big`/`too_small` issues are enriched; string,
array, and file-size origins are left unchanged.
Fixes#52500
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(config): update maxFileBytes test for numeric bound hint
The test snapshot for `logging.maxFileBytes: 0` rejection now includes
the `(must be greater than 0)` hint appended by the numeric bound
enrichment added in the previous commit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(config): guard nullable record in appendNumericBoundHint call
ClawSweeper P1: `record` from `toIssueRecord()` can be null, but
`appendNumericBoundHint` expects a non-null `UnknownIssueRecord`.
Guard with a ternary so the original message is returned when record
is null (which only happens for malformed/empty issues that already
produce generic "Invalid input" messages).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(diffs): replace iconMarkup string with ToolbarIconName enum to eliminate XSS sink
Replace createToolbarButton's iconMarkup: string parameter with icon: ToolbarIconName,
a union of known icon names. SVG generation moves into a sealed toolbarIconSvg map so
innerHTML only receives compile-time-known strings. The old splitIcon/unifiedIcon/
wrapIcon/backgroundIcon/themeIcon functions are removed; callers now pass icon name
literals instead of raw markup strings.
Closes#83918
* fix(diffs): remove jsdom dependency from viewer-client test
Use source file string analysis instead of jsdom to avoid missing
@types/jsdom declaration error in check-test-types CI job.
* fix(diffs): restore wrap icon arrow segment in ToolbarIconName map
The wrap-on and wrap-off SVG paths were missing the original wrap arrow
segment (M14 6h-4V5h4.5...). Restore the exact original path data and
rebuild the viewer runtime bundle.
* build(diffs): refresh viewer runtime after rebase
---------
Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary:
- The PR adds a diagnostics-otel scoped unhandled-rejection handler for nested OTLPExporterError values, unregisters it on stop/restart, adds regression tests, and adds a changelog entry.
- Reproducibility: yes. The source path is high-confidence: current main has no OTLPExporterError-specific dia ... ror for non-retryable OTLP HTTP failures; I did not run a live collector shutdown in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(diagnostics-otel): avoid stale exporter handler
- PR branch already contained follow-up commit before automerge: fix(diagnostics-otel): suppress exporter rejection crashes
Validation:
- ClawSweeper review passed for head e19c06c992.
- Required merge gates passed before the squash merge.
Prepared head SHA: e19c06c992
Review: https://github.com/openclaw/openclaw/pull/84881#issuecomment-4506249586
Co-authored-by: luoyanglang <hanwanlonga@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This replacement PR marks the Linux node daemon gateway token as file-backed, writes it to `node.systemd.env`, sanitizes and migrates systemd env artifacts, adds regression tests, and updates the changelog.
- Reproducibility: yes. from source inspection: current `main` copies `OPENCLAW_GATEWAY_TOKEN` into the node s ... e-backed before systemd rendering. I did not run a local live systemd install during this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(systemd): scrub single-quoted env tokens
- PR branch already contained follow-up commit before automerge: [Fix] Keep node systemd tokens out of unit files
Validation:
- ClawSweeper review passed for head f626b66c09.
- Required merge gates passed before the squash merge.
Prepared head SHA: f626b66c09
Review: https://github.com/openclaw/openclaw/pull/84815#issuecomment-4505012292
Co-authored-by: samzong <samzong.lu@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR disables pi-coding-agent auto-retry inside prepared embedded Pi settings, updates the focused settings test, and moves the changelog entry into Unreleased.
- Reproducibility: yes. source-reproducible: current main leaves embedded Pi retry enabled, while pi-coding-ag ... e assistant error before continuing. I did not run a live Feishu/Qwen replay loop in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(agents): disable pi-coding-agent auto-retry to prevent tool call …
Validation:
- ClawSweeper review passed for head ca745fd55d.
- Required merge gates passed before the squash merge.
Prepared head SHA: ca745fd55d
Review: https://github.com/openclaw/openclaw/pull/84798#issuecomment-4504702875
Co-authored-by: yelog <yelogeek@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR filters partial skill snapshot entries in trajectory support metadata, accepts nullish support-redaction paths, adds regression tests, and records the fix in the changelog.
- Reproducibility: yes. Source inspection on current main shows undefined skill path/name values can reach str ... and the related source PR provides redacted live before/after gateway logs for the symlink-escape scenario.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(trajectory): tighten test types for partial skill entries
- PR branch already contained follow-up commit before automerge: fix(trajectory): tolerate partial skill snapshot entries in support c…
Validation:
- ClawSweeper review passed for head ecb3df6c08.
- Required merge gates passed before the squash merge.
Prepared head SHA: ecb3df6c08
Review: https://github.com/openclaw/openclaw/pull/84797#issuecomment-4504703074
Co-authored-by: Luke Boyett <46942646+lukeboyett@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Widen the Control UI settings Personal quick-settings card to the intended 3/1 desktop split, keep Personal before Appearance/Automations at the narrower layout, and make the focused CSS assertions tolerant of harmless formatting changes.
Verification:
- pnpm --dir ui test src/styles/config-quick.test.ts
- pnpm exec oxfmt --check --threads=1 ui/src/styles/config-quick.test.ts
- git diff --check
- GitHub CI on 4c8f6d7f50
Lazy-load agents CLI action modules from command callbacks so agents --help avoids importing the full agents runtime.
Validated by GitHub required checks and local focused CLI gates.
Summary:
- The PR changes sherpa-onnx CLI audio parsing so structured JSON with an empty `text` field becomes no transcript, while preserving non-empty JSON extraction and adding direct plus auto-detect regression coverage.
- Reproducibility: yes. Source inspection on current main shows empty sherpa structured JSON misses extraction ... scord voice can skip empty transcripts; I did not run a live Discord reproduction in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Fix stale CI guardrails for sherpa transcript PR
- PR branch already contained follow-up commit before automerge: Skip empty sherpa structured transcripts
Validation:
- ClawSweeper review passed for head ac03171cfc.
- Required merge gates passed before the squash merge.
Prepared head SHA: ac03171cfc
Review: https://github.com/openclaw/openclaw/pull/84667#issuecomment-4501484167
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR removes MiniMax music duration support from provider capabilities and docs, stops prompt-injecting duration hints, updates the MiniMax provider test, and adds a changelog entry.
- Reproducibility: yes. by source inspection: current main advertises MiniMax duration support while the reque ... uage hint. I did not rerun a live pre-fix MiniMax request, but the code path and vendor contract are clear.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs(minimax): align music controls
- PR branch already contained follow-up commit before automerge: docs(music): remove minimax duration steering claim
- PR branch already contained follow-up commit before automerge: fix(minimax): stop advertising music duration control
Validation:
- ClawSweeper review passed for head 1c616da45c.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1c616da45c
Review: https://github.com/openclaw/openclaw/pull/84765#issuecomment-4504176794
Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates Codex app-server system-prompt reporting to tolerate bootstrap files with `path` and `content` but no `name`, adds a focused regression test, and records the fix in the changelog.
- Reproducibility: yes. The PR body supplies current-main before output with the `undefined.trim()` stack, and source inspection confirms hook-supplied path-only bootstrap files can reach the Codex report helper.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(codex): guard path-only bootstrap files [AI-assisted]
Validation:
- ClawSweeper review passed for head 4667110899.
- Required merge gates passed before the squash merge.
Prepared head SHA: 4667110899
Review: https://github.com/openclaw/openclaw/pull/84736#issuecomment-4503672362
Co-authored-by: JARVIS-Glasses <whatsskilll@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- Adds a `doctor` security warning for plaintext secret-bearing `openclaw.json` fields by reusing the secrets target registry and shared model-provider header sensitivity policy.
- Reproducibility: yes. for source-level behavior: current main has plaintext secret audit coverage but no doc ... llector for those config targets, and the PR body includes live patched CLI output showing the new warning.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Warn on plaintext secret config in doctor
Validation:
- ClawSweeper review passed for head 31f83aae19.
- Required merge gates passed before the squash merge.
Prepared head SHA: 31f83aae19
Review: https://github.com/openclaw/openclaw/pull/84718#issuecomment-4503210496
Co-authored-by: qingsenlab <qingsenlab@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR removes the legacy `cat SKILL.md && printf ... && <skill-wrapper>` exec-approval allowlist path, updates focused exec-approval tests, and adds a changelog entry.
- Reproducibility: yes. Current-main source and tests show the old `cat SKILL.md && printf ... && <wrapper>` c ... ed this by source and test inspection rather than executing tests because the checkout review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Remove skill prelude exec allowlist
Validation:
- ClawSweeper review passed for head 0ca7f3e8ef.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0ca7f3e8ef
Review: https://github.com/openclaw/openclaw/pull/84570#issuecomment-4498357535
Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: jesse-merhi
* perf(tui): skip plugin-aware config validation on remote TUI startup
Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.
Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:
- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
still gets a fully validated config
* remove verbose comments
* perf(tui): move context cache warmup from module top-level to embedded backend
agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).
It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.
Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.
* perf(tui): defer EmbeddedTuiBackend import until local mode
* refactor(agents): remove dead context-cache warmup helpers
* perf(tui): skip plugin-aware config validation on remote TUI startup
Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.
Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:
- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
still gets a fully validated config
* remove verbose comments
* perf(tui): move context cache warmup from module top-level to embedded backend
agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).
It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.
Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.
Summary:
- The PR extracts JSON-mode console-to-stderr routing into a shared CLI helper, wraps root and `nodes` lazy plugin registration, adds nodes registration coverage, and adds a changelog entry.
- Reproducibility: yes. for source-level reproduction: the linked report shows `openclaw nodes list --json 2> ... ssing the existing JSON stderr guard. I did not run the live Helm/container repro in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Route JSON-mode plugin registration logs to stderr
Validation:
- ClawSweeper review passed for head c9d0867db0.
- Required merge gates passed before the squash merge.
Prepared head SHA: c9d0867db0
Review: https://github.com/openclaw/openclaw/pull/84741#issuecomment-4503741078
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* build: suppress rolldown-plugin-dts CommonJS dts warnings from bundled zod locales
After bumping rolldown-plugin-dts to 0.25.1 (94ac563399), every
`pnpm build` emits a 'CommonJS dts' warning per zod `v4/locales/*.d.cts`
file because zod is intentionally inlined for global pnpm install
resolution (#78515) and tsdown's external option cannot be scoped to the
dts pass only. Filter the warning in the existing onLog suppression list
(same pattern as PLUGIN_TIMINGS / UNRESOLVED_IMPORT / EVAL) so other
rolldown-plugin-dts warnings remain visible.
* docs(changelog): move rolldown-dts entry into 2026.5.20 fixes
Summary:
- The PR updates the macOS About settings copyright text to 2026, adds a changelog entry, and adjusts changed-check planning so non-macOS hosts without SwiftLint emit an explicit app-lint skip with matching test coverage.
- Reproducibility: yes. from source inspection: current main still renders the 2025 copyright literal in the m ... launch the app locally, but the source path and source PR proof make the observable issue high-confidence.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8438…
Validation:
- ClawSweeper review passed for head 26816c18d6.
- Required merge gates passed before the squash merge.
Prepared head SHA: 26816c18d6
Review: https://github.com/openclaw/openclaw/pull/84729#issuecomment-4503529931
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Followup nits from the #84711 review:
- Narrow the inspectTokenFile catch in
extensions/telegram/src/account-inspect.ts to FsSafeError so only
fs-safe validation throws map to configured_unavailable; any other
throw (programmer error, unexpected I/O) is rethrown.
- Add a regression test for the IRC NickServ password file symlink
rejection path (extensions/irc/src/accounts.ts:118), paralleling the
existing top-level passwordFile test.
- Add a regression test for the Telegram account-level tokenFile
symlink rejection path (extensions/telegram/src/token.ts:149),
paralleling the existing channel-level tokenFile test.
Behavior was already correct after #84711; this just locks coverage and
tightens the catch.
* fix(infra): restore symlink rejection in tryReadSecretFileSync
The local wrapper added in 9e4eca00ff swallowed all errors from
@openclaw/fs-safe@0.2.7's tryReadSecretFileSync via a bare try/catch,
silently downgrading every rejectSymlink: true caller (Telegram, LINE,
Zalo, IRC, Nextcloud Talk credential files) to accept symlinked
credential files. It also broke the infra-state CI shard's symlink
expectation that #84595 had just realigned with the new fail-closed
upstream contract.
Restore the direct re-export so the upstream contract surfaces:
undefined for blank/missing/not-found, FsSafeError for symlink,
oversize, non-regular file, and hardlink validation failures.
* test(plugins): align stale symlink tests with fail-closed contract
5 token/account resolver tests still asserted the pre-fs-safe-0.2.7
"silent skip" behavior (token: "", source: "none") on rejected symlinks;
they passed only because the swallow-all wrapper in secret-file.ts hid
the throw. Restoring the upstream fail-closed contract surfaces the
throw, so update the tests to expect FsSafeError.
inspectTelegramAccount reports credential status (its return type has an
explicit configured_unavailable state for "configured but unreadable"),
so its callsite is the right boundary to catch the FsSafeError and map
it to configured_unavailable rather than letting the throw bubble.
Affected:
- extensions/zalo/src/token.test.ts
- extensions/line/src/accounts.test.ts
- extensions/telegram/src/token.test.ts
- extensions/irc/src/accounts.test.ts
- extensions/nextcloud-talk/src/setup.test.ts
- extensions/telegram/src/account-inspect.ts (catch + report status)
Summary:
- This PR filters exported sub-CLI descriptors through the private-QA gate, centralizes that filter, adds regr ... ge, and carries small validation repairs in workspace glob and tunnel-timeout tests plus a changelog entry.
- Reproducibility: yes. Current-main source shows the raw SUB_CLI_DESCRIPTORS export can include qa while the helper surfaces filter it, and src/cli/argv.ts consumes that export for root command policy.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): gate exported subcli descriptors
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8451…
Validation:
- ClawSweeper review passed for head ba197a6f30.
- Required merge gates passed before the squash merge.
Prepared head SHA: ba197a6f30
Review: https://github.com/openclaw/openclaw/pull/84519#issuecomment-4496549642
Co-authored-by: Zhaocun <zhaocunsun@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch threads `agents.defaults.imageMaxDimensionPx` into browser screenshot and labeled snapshot image results, adds regression coverage and a changelog entry, and includes small repair-pass type/lint cleanup.
- Reproducibility: yes. source-level reproduction is high confidence: current `main` calls `imageResultFromFil ... both browser image-returning paths, while the shared sanitizer falls back to `1200px` without an override.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(browser): honor image sanitization config for screenshots
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8459…
Validation:
- ClawSweeper review passed for head c01fde7990.
- Required merge gates passed before the squash merge.
Prepared head SHA: c01fde7990
Review: https://github.com/openclaw/openclaw/pull/84595#issuecomment-4499178477
Co-authored-by: Xu Xiang <xx205@outlook.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Add bounded realtime profile context for Discord realtime voice sessions.
Default to `IDENTITY.md`, `USER.md`, and `SOUL.md`; `voice.realtime.bootstrapContextFiles: []` disables the extra context.
Document the config/SDK surface and refresh generated metadata.
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Summary:
- The PR updates `src/cli/shared/parse-port.test.ts` to cover numeric strings, whitespace-padded strings, fractional strings, invalid suffixes, and safe-integer overflow for `parsePort`.
- Reproducibility: not applicable. This PR adds test coverage rather than reporting a failing runtime behavior. Source inspection confirms the current parser contract and the exact baseline coverage gap on main.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 14213cc8f4.
- Required merge gates passed before the squash merge.
Prepared head SHA: 14213cc8f4
Review: https://github.com/openclaw/openclaw/pull/84518#issuecomment-4496552268
Co-authored-by: googlerest <127843198+googlerest@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Fixes openclaw#84386. resolveActiveProfileId in extensions/codex/src/command-account.ts returned store.lastGood whenever that profile was still in the resolved order, ignoring rank, so /codex account marked the stale openai-codex:default profile as active after models auth login + models auth order set. Tracks whether the order came from an explicit operator source (store.order / config.auth.order, including the openai alias key), picks the first usable explicit-order profile, and returns undefined when no candidate is eligible so the display surfaces "no working credential" instead of marking a lower-ranked profile active. Runtime selection via resolveCodexAppServerAuthProfileId is unchanged.
* perf(plugins): extend discovery threading to loader, manifest registry, installed-index, and config contracts
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
* perf(plugins): drop verbose JSDoc from discovery? params
* perf(plugins): scan-scoped package.json cache in discovery
Adds a per-scan Map<string, PackageManifest | null> threaded through
discoverFromPath/discoverInDirectory/readCandidatePackageManifest, keyed
by the directory's resolved real path. Within one discovery scan, a
plugin's package.json is now read from disk once and reused across the
overlapping discovery code paths (bundled overlay scan, stock-root scan,
source-checkout extensions scan, installed-path scan, global-root scan)
that previously each fired their own read.
The cache lifetime is one scan (created in runPluginDiscovery alongside
the existing realpathCache and seen Set, dies when the scan returns).
discoverOpenClawPlugins remains stateless externally; no persistent
metadata cache.
* perf(plugins): expose raw parsed package.json on PluginCandidate
Discovery already reads each plugin's package.json once and produces a
parsed PackageManifest object before distilling it into metadata via
getPackageManifestMetadata. Currently only the distilled metadata is
kept on the candidate; the full parsed manifest is discarded.
Store the full parsed manifest on rawPackageManifest so downstream
consumers iterating candidates can use it instead of re-reading from
disk. This is the candidate-side groundwork for the scenario-C followup
that routes consumers (bundled-plugin-metadata, bundle-* helpers, etc.)
through the cached field; those consumers currently do their own
directory scans and would need to be refactored to iterate
PluginCandidate arrays before they can benefit.
The field is a frozen-at-discovery-time snapshot, same lifetime semantics
as the existing packageManifest / packageName / packageVersion fields on
PluginCandidate. No new staleness window introduced.
* perf(plugins): make package-manifest cache key trust-aware
Summary:
- Adds a 50-page and advancing-`nextOffset` guard to `loadCronJobForShow`, exports that helper for regression tests, and adds an unreleased changelog entry.
- Reproducibility: yes. Current main is source-reproducible because `loadCronJobForShow` loops while `hasMore` ... ed numeric `nextOffset`; the PR discussion also includes terminal before/after proof for the same CLI path.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 7828b4bdae.
- Required merge gates passed before the squash merge.
Prepared head SHA: 7828b4bdae
Review: https://github.com/openclaw/openclaw/pull/83989#issuecomment-4484474655
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The replacement branch adds an owned transcript write context around Pi prompt-time delivery mirror appends and a message-tool-only terminal hook, with focused tests and a changelog entry.
- Reproducibility: yes. the source PR includes before/after redacted live Discord logs for a message-tool-only ... ession-lock and transcript append code. I did not rerun the live Discord scenario in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(pi): keep message-tool delivery in session lock
Validation:
- ClawSweeper review passed for head f16678175c.
- Required merge gates passed before the squash merge.
Prepared head SHA: f16678175c
Review: https://github.com/openclaw/openclaw/pull/84437#issuecomment-4494545360
Co-authored-by: Andrew Meyer <andrewmeyer@andrews-air.lan>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR changes cron store loading to normalize legacy top-level array `jobs.json` files into the versioned store shape and adds store, service, doctor, gateway tests plus a changelog entry.
- Reproducibility: yes. Current `main` clearly maps a top-level parsed array to `{}` before reading `.jobs`, and the PR body supplies before/after runtime output for the load/add/save path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: [AI-assisted] fix(cron): preserve legacy array stores
Validation:
- ClawSweeper review passed for head 446014b4c1.
- Required merge gates passed before the squash merge.
Prepared head SHA: 446014b4c1
Review: https://github.com/openclaw/openclaw/pull/84433#issuecomment-4494478724
Co-authored-by: JARVIS-Glasses <284122573+JARVIS-Glasses@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds a Warning block to `docs/channels/imessage.md` explaining that iMessage `cliPath` wrappers and SSH proxies must stream long-lived JSON-RPC stdin/stdout incrementally.
- Reproducibility: not applicable. for this docs-only PR. Source inspection verifies the runtime uses long-lived line-framed stdio, and current main lacks the operator warning being added.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs(imessage): warn that cliPath wrappers must stream JSON-RPC stdio…
Validation:
- ClawSweeper review passed for head a371ee998e.
- Required merge gates passed before the squash merge.
Prepared head SHA: a371ee998e
Review: https://github.com/openclaw/openclaw/pull/84420#issuecomment-4494313781
Co-authored-by: HCL <chenglunhu@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch caps async diagnostic drains at 100 events per turn, adds pending/full-drain diagnostic helpers, ... rminal diagnostics to inspect pending events, and adds regression coverage plus changelog/baseline updates.
- Reproducibility: yes. from source inspection. Current main drains the entire async diagnostic queue in one s ... ck, and the PR body supplies a focused 250-event after-fix probe showing 100/200/250 delivery across turns.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: yield diagnostic event drains
Validation:
- ClawSweeper review passed for head 95610934cd.
- Required merge gates passed before the squash merge.
Prepared head SHA: 95610934cd
Review: https://github.com/openclaw/openclaw/pull/82937#issuecomment-4469498220
Co-authored-by: Galin Iliev <galini@microsoft.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Marks skipped and supplemental Microsoft Teams system events as non-owner/untrusted while preserving active primary message dispatch behavior.
Verified before merge:
- PR was open, not draft, mergeable, and clean against main
- Matched head: 4f79f46205
- GitHub checks passed, including Real behavior proof, auto-response, build artifacts, type/lint checks, channel/runtime critical quality checks, and security-fast
- ClawSweeper marked proof sufficient with no concrete contributor-facing blocker remaining
Co-authored-by: GuoJiaming <804436395@qq.com>
Summary:
- The branch gives Codex `image_generate` dynamic-tool calls a 120s default watchdog in main and side-thread paths and updates docs, tests, and changelog.
- Reproducibility: yes. Source inspection on current main shows unconfigured Codex `image_generate` calls fall ... -tool default, and the linked source PR includes live Gateway before/after output for the timeout behavior.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8425…
- PR branch already contained follow-up commit before automerge: Fix Codex image generation tool timeout
Validation:
- ClawSweeper review passed for head 10c7f87023.
- Required merge gates passed before the squash merge.
Prepared head SHA: 10c7f87023
Review: https://github.com/openclaw/openclaw/pull/84369#issuecomment-4493288493
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: moritzmmayerhofer <254141390+moritzmmayerhofer@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates the code-mode exec tool description, adds regression coverage for the model-visible constraints, and records the fix in the changelog.
- Reproducibility: yes. at source level: current main's exec schema omits constraints that the current code-mo ... also includes a live before/after recitation path showing the model receives the changed tool description.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(code-mode): cover exec tool guidance
- PR branch already contained follow-up commit before automerge: fix(code-mode): sharpen exec tool description so models stop wasting …
Validation:
- ClawSweeper review passed for head 8ff85071ce.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8ff85071ce
Review: https://github.com/openclaw/openclaw/pull/84368#issuecomment-4493273853
Co-authored-by: Kaspre <kaspre@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates Gateway agent summary builders to use `agents.list[].identity.name` when explicit `agents.list[].name` is absent, adds focused gateway regression tests, and records a changelog fix.
- Reproducibility: yes. Current main can be source-reproduced: both gateway summary builders set top-level `na ... list[].name`, so identity-only configured agents have no summary name for consumers that read `agent.name`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(gateway): cover missing agent summary names
- PR branch already contained follow-up commit before automerge: fix(gateway): remove stale name fallback import
- PR branch already contained follow-up commit before automerge: gateway: use identity.name in agent summaries when name is unset
Validation:
- ClawSweeper review passed for head 9f7024f55c.
- Required merge gates passed before the squash merge.
Prepared head SHA: 9f7024f55c
Review: https://github.com/openclaw/openclaw/pull/84355#issuecomment-4493008710
Co-authored-by: luoyanglang <hanwanlonga@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR promotes direct or nested send receipt IDs into `openclaw message send --json`, adds a focused command test, and adds a changelog entry.
- Reproducibility: yes. at source level. Current main serializes only the raw payload while send receipts can carry `payload.result.messageId`; I did not execute the CLI in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(cli): fix message json payload type
- PR branch already contained follow-up commit before automerge: chore: retrigger PR checks
- PR branch already contained follow-up commit before automerge: Expose messageId in message CLI JSON output
Validation:
- ClawSweeper review passed for head 9eba815fcc.
- Required merge gates passed before the squash merge.
Prepared head SHA: 9eba815fcc
Review: https://github.com/openclaw/openclaw/pull/84191#issuecomment-4489100591
Co-authored-by: OpenClaw Contributor <100menotu001@users.noreply.github.com>
Co-authored-by: Craig <froelich@craigs.mac.studio.froho>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Summary:
- Adds `disabled` to the message presentation button schema, advertises Discord disabled-button support, prese ... through Discord component mapping and link serialization, and adds regression tests plus a changelog entry.
- Reproducibility: yes. Source inspection on current main shows `disabled` exists in the runtime type but is a ... rtised in Discord capabilities, dropped by adaptation, and omitted from Discord mapping/link serialization.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(discord): advertise disabled presentation support
- PR branch already contained follow-up commit before automerge: fix(discord): preserve disabled link buttons
- PR branch already contained follow-up commit before automerge: Preserve disabled Discord presentation buttons
Validation:
- ClawSweeper review passed for head 9bb60d8cbf.
- Required merge gates passed before the squash merge.
Prepared head SHA: 9bb60d8cbf
Review: https://github.com/openclaw/openclaw/pull/84312#issuecomment-4491983845
Co-authored-by: OpenClaw Contributor <100menotu001@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR adds scoped truncation and hover titles to usage-panel context-breakdown names and adds a changelog entry crediting the source PR.
- Reproducibility: yes. at source/proof level: current main renders long context names without truncation or t ... he overflow before and ellipsis/tooltip after. I did not run a live browser session in this read-only pass.
Automerge notes:
- PR branch already contained follow-up commit before automerge: feat(ui): tool name style in usage panel
Validation:
- ClawSweeper review passed for head 396e405b3b.
- Required merge gates passed before the squash merge.
Prepared head SHA: 396e405b3b
Review: https://github.com/openclaw/openclaw/pull/84310#issuecomment-4491942108
Co-authored-by: Rain120 <1085131904@qq.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* perf(plugins): extend discovery threading to loader, manifest registry, installed-index, and config contracts
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
* perf(plugins): drop verbose JSDoc from discovery? params
Summary:
- The PR updates `src/infra/clawhub.ts` URL joining, adds a path-prefix regression test in `src/infra/clawhub.test.ts`, and adds a changelog bullet.
- Reproducibility: yes. Source inspection plus a direct Node URL check show current main drops `/clawhub` when resolving a leading-slash API path against a prefixed base URL.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(clawhub): preserve base URL path prefix [AI-assisted]
Validation:
- ClawSweeper review passed for head 7bb2cb8764.
- Required merge gates passed before the squash merge.
Prepared head SHA: 7bb2cb8764
Review: https://github.com/openclaw/openclaw/pull/83982#issuecomment-4484348274
Co-authored-by: Thiago Costa <thiago12_fera@hotmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Fixes#83901. Honors Commander negated option handling for ACP prompt-prefix forwarding and adds focused CLI regression coverage. Verified with Crabbox AWS cbx_1689d0ad78e9 run run_a406418db6fe and Real behavior proof run 26127392365.
Summary:
- The PR registers Twitch refreshing-token users with Twurple's chat intent and adds regression coverage for that contract.
- Reproducibility: yes. by source and dependency contract. Current main does not register the chat intent, and ... RefreshingAuthProvider only resolves getAccessTokenForIntent('chat') when that intent is mapped to a user.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(twitch): register chat intent for refreshing auth
Validation:
- ClawSweeper review passed for head 1fdadcff04.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1fdadcff04
Review: https://github.com/openclaw/openclaw/pull/83750#issuecomment-4481748086
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Summary:
- The PR pins managed Gateway package updates, runtime preflight, post-install doctor, post-core update, service refresh, and restart follow-ups to the Node binary and package root baked into the Gateway service.
- Reproducibility: yes. source-level. Current main validates and follows up with the shell process Node in the ... body provides a concrete two-Node Docker reproduction, though I did not execute it in this read-only pass.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(update): detect service node mismatch even when package roots match
- PR branch already contained follow-up commit before automerge: fix(update): pin package install to service root when nodes differ wi…
Validation:
- ClawSweeper review passed for head 5607e441f6.
- Required merge gates passed before the squash merge.
Prepared head SHA: 5607e441f6
Review: https://github.com/openclaw/openclaw/pull/84043#issuecomment-4485613931
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <aknight@atlassian.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: amknight
Co-authored-by: amknight <15041791+amknight@users.noreply.github.com>
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
Add optional discovery parameter to loadBundledCapabilityRuntimeRegistry,
resolveBundledPluginSources, and listChannelCatalogEntries so callers
that already hold a PluginDiscoveryResult can skip redundant filesystem
walks.
In contracts/registry.ts, the retry loop in
loadScopedCapabilityRuntimeRegistryEntries computes discovery once
and shares it across retry attempts (function-scoped, not module-scoped).
discoverOpenClawPlugins() itself remains stateless with no hidden cache.
Closes#82308
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Summary:
- The PR changes one bullet in `docs/tools/slash-commands.md` to distinguish `/new` from `/reset` and remove the misleading alias wording.
- Reproducibility: yes. Reading current main reproduces the misleading docs line at `docs/tools/slash-commands.md:127`, and adjacent source/tests show `/new` and `/reset` take different paths in the Control UI.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs/slash-commands: drop inaccurate Control UI/ACP cross-reference (…
- PR branch already contained follow-up commit before automerge: Merge branch 'main' into docs/fix-reset-alias-misleading
Validation:
- ClawSweeper review passed for head bb92b6050a.
- Required merge gates passed before the squash merge.
Prepared head SHA: bb92b6050a
Review: https://github.com/openclaw/openclaw/pull/81073#issuecomment-4432165259
Co-authored-by: Md. Al-Mosabbir Rakib <mrakib50.cse@gmail.com>
Co-authored-by: Md. Al-Mosabbir Rakib <34891461+mosabbirrakib@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates `docs/cli/gateway.md` and `docs/reference/test.md` to document Gateway startup/restart benchmark prerequisites, commands, case IDs, probes, output semantics, and platform limits.
- Reproducibility: not applicable. as a runtime bug; docs correctness is source-checkable against the benchmar ... ipts, and readiness source. The current PR head corrected the earlier startup-hook readiness wording issue.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs(gateway): correct benchmark readiness wording
Validation:
- ClawSweeper review passed for head 5bd0f6c463.
- Required merge gates passed before the squash merge.
Prepared head SHA: 5bd0f6c463
Review: https://github.com/openclaw/openclaw/pull/83866#issuecomment-4483820005
Co-authored-by: samzong <samzong.lu@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
The schema.help text for `models.providers.*.timeoutSeconds` documents the
key as the user-facing knob for "slow local or self-hosted model servers".
In practice the option is also the only configurable lever for the LLM
idle/first-token watchdog. However `resolveLlmIdleTimeoutMs` was still
running the explicit provider timeout through `clampImplicitTimeoutMs`,
clamping it back down to the implicit ~120s `DEFAULT_LLM_IDLE_TIMEOUT_MS`
ceiling for any non-cron, non-local provider.
Consequence (matches #77744 and #78361):
- User sets `models.providers.llamacpp.timeoutSeconds: 14400` (or 600 for
a slow Gemini/Opus turn with a large tool payload).
- Hot reload accepts the value, runtime resolves
`modelRequestTimeoutMs = 14_400_000`.
- Idle watchdog still trips at ~120s with
"LLM idle timeout (120s): no response from model", aborting an
otherwise-healthy upstream that is mid-prefill or buffering thinking
tokens.
Fix: when the caller passes an explicit `modelRequestTimeoutMs`
(sourced from `models.providers.<id>.timeoutSeconds` /
`model.requestTimeoutMs`), treat it as a deliberate ceiling for cloud
providers too. The run-timeout / agent-timeout bounds still apply via
`timeoutBounds`, so a shorter explicit run timeout always wins. The
implicit default watchdog still kicks in when the user has not set a
provider timeout, preserving the network-silence-as-hang guard for
default configs.
Updated the two corresponding test cases that asserted the old
clamp-on-cloud behavior; all 71 tests in `llm-idle-timeout.test.ts`
and the wider 430-test `src/agents/pi-embedded-runner/run/` lane pass.
Schema help text refreshed to call out that the same knob raises the
idle watchdog ceiling.
Refs: #77744, #78361
Summary:
- The PR changes `openclaw acp client` error handling to use `formatErrorMessage`, adds a plain-object rejection regression test, and adds a changelog entry.
- Reproducibility: yes. Current main visibly sends `openclaw acp client` caught errors through `String(err)`, ... catch already uses `formatErrorMessage`; I did not run a live failing ACP server in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): format acp client errors with formatErrorMessage (#83904)
Validation:
- ClawSweeper review passed for head 69ef0e7270.
- Required merge gates passed before the squash merge.
Prepared head SHA: 69ef0e7270
Review: https://github.com/openclaw/openclaw/pull/84080#issuecomment-4486666922
Co-authored-by: HCL <chenglunhu@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch adds per-agent `agents.list[].experimental.localModelLean` config and applies lean tool filtering through agent, session, and default-agent resolution.
- Reproducibility: not applicable. this is a feature/config PR rather than a current-main bug report. The chan ... or is supported by source review, focused tests in the branch, and the PR body's redacted live runtime log.
Automerge notes:
- PR branch already contained follow-up commit before automerge: feat(agents): support per-agent local model lean mode
- PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8407…
Validation:
- ClawSweeper review passed for head 1f9a9554da.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1f9a9554da
Review: https://github.com/openclaw/openclaw/pull/84073#issuecomment-4486397570
Co-authored-by: Bob <dutifulbob@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Summary:
- The PR updates `openclaw channels logs` tail-window reading to keep a complete first line when the 1 MB window starts on a newline boundary, adds a regression test, and adds a changelog entry.
- Reproducibility: yes. Source inspection on current main shows the unconditional first-line drop, and the PR ... s provide terminal before/after CLI output for a 2 MB log whose tail window starts exactly after a newline.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/channels-logs-dro…
- PR branch already contained follow-up commit before automerge: fix(cli): preserve first line of channels logs at window boundary
Validation:
- ClawSweeper review passed for head 284b312b31.
- Required merge gates passed before the squash merge.
Prepared head SHA: 284b312b31
Review: https://github.com/openclaw/openclaw/pull/84106#issuecomment-4487313048
Co-authored-by: BSG2000 <bsg2000@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch updates queue-by-channel config schema/types for Matrix, Google Chat, and Mattermost, refreshes config baseline hashes, adds config/schema regression tests, and records the user-visible fix in the changelog.
- Reproducibility: yes. Source inspection gives a high-confidence path: current main's strict `messages.queue. ... matrix`, and the linked source PR records the same config failing before the patch and validating after it.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 3865178550.
- Required merge gates passed before the squash merge.
Prepared head SHA: 3865178550
Review: https://github.com/openclaw/openclaw/pull/84104#issuecomment-4487285061
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- Adds shared Control UI session-run active-state handling, applies terminal-status precedence in chat/session rendering and lifecycle recovery, and adds focused regressions plus a changelog entry.
- Reproducibility: yes. Current main has a source-visible path where `status: "done"` plus stale `hasActiveRun ... eeps abort/in-progress UI alive, and the linked proof exercises the fixed stale-terminal state in Chromium.
Automerge notes:
- PR branch already contained follow-up commit before automerge: [codex] Fix Control UI terminal run status recovery
Validation:
- ClawSweeper review passed for head f9f503add0.
- Required merge gates passed before the squash merge.
Prepared head SHA: f9f503add0
Review: https://github.com/openclaw/openclaw/pull/84112#issuecomment-4487409085
Co-authored-by: NianJiuZst <3235467914@qq.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR updates CLI root option parsing to preserve embedded equals signs, adds focused Vitest coverage for inline and space-separated values, and records the fix in the changelog.
- Reproducibility: yes. by source inspection: current main uses `raw.split("=", 2)`, so `--token=abc=def` returns only `abc`; the PR body also supplies after-fix live output for the same path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): preserve equals in root option values [AI-assisted]
Validation:
- ClawSweeper review passed for head 8a15801e79.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8a15801e79
Review: https://github.com/openclaw/openclaw/pull/84107#issuecomment-4487314163
Co-authored-by: Thiago Costa <thiago12_fera@hotmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds a 65,535 upper-bound check to the shared CLI `parsePort` helper, a colocated regression test, and a changelog entry for the linked port-range bug.
- Reproducibility: yes. Source inspection on current main shows `parsePort('99999')` delegates to `parseStrict ... sitive safe integer, so the return would be `99999`; I did not execute it because this review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): reject out-of-range port numbers in parsePort (#83900)
Validation:
- ClawSweeper review passed for head 9ad0705c44.
- Required merge gates passed before the squash merge.
Prepared head SHA: 9ad0705c44
Review: https://github.com/openclaw/openclaw/pull/84008#issuecomment-4484883200
Co-authored-by: HCL <chenglunhu@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR moves the existing Motivation section in `.github/pull_request_template.md` from below Linked Issue/PR to immediately after Summary without changing the section text.
- Reproducibility: not applicable. this is a PR-template ordering cleanup, not a runtime bug. Source inspection of current main and the PR head verifies the before/after section order.
Automerge notes:
- PR branch already contained follow-up commit before automerge: chore: move Motivation section above Change Type in PR template
Validation:
- ClawSweeper review passed for head 6c68583fac.
- Required merge gates passed before the squash merge.
Prepared head SHA: 6c68583fac
Review: https://github.com/openclaw/openclaw/pull/84098#issuecomment-4487082864
Co-authored-by: Huan Jiang <seraphjiang@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch makes unknown-capabilities Ollama model definitions explicitly tool-capable, adds regression assertions and changelog text, and guards the issue-labeler job to run only on issue events.
- Reproducibility: yes. for the metadata gap: current main builds unknown-capabilities Ollama models without a ... er-fix live provider output with `supportsTools: true`. I did not run local tests in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ollama): default unknown capabilities to tools
Validation:
- ClawSweeper review passed for head 27527716c0.
- Required merge gates passed before the squash merge.
Prepared head SHA: 27527716c0
Review: https://github.com/openclaw/openclaw/pull/84075#issuecomment-4486492661
Co-authored-by: Bob <dutifulbob@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Summary:
- The branch adds a close lifecycle for local memory embedding providers, scoped memory search/index teardown for one agent, Active Memory timeout cleanup, focused tests, and a changelog entry.
- Reproducibility: yes. The linked issue gives a concrete OpenClaw 2026.5.18 Telegram Active Memory timeout pa ... current-main source inspection confirms there is no timeout cleanup for that local embedding provider path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(memory): close local embedding providers on timeout
Validation:
- ClawSweeper review passed for head 8e2e369b5c.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8e2e369b5c
Review: https://github.com/openclaw/openclaw/pull/84048#issuecomment-4485705481
Co-authored-by: brokemac79 <martin_cleary@yahoo.co.uk>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Adds bounded queued-writer diagnostics to pi-trajectory-flush cleanup timeout warnings so operators can see pending write count, queued bytes, active operation, and append size without exposing paths or payloads.
Closes#82961
Recover stale subagent completion delivery by retrying unsupported transcript-wait wakes without transcript waiting and forcing the existing message-tool handoff when the requester run is stale and direct completion is invisible.\n\nAdds regression coverage for the stale wake sequence and records the maintainer changelog entry.\n\nFixes #83699.
* fix config provider timeout overlays
Allow bundled model provider config entries to act as overlays so fields like timeoutSeconds can be configured without redeclaring baseUrl and models. Keep unknown custom provider declarations strict, and guard configured-provider fallback against overlay entries without models.
* fix(config): include provider aliases in model overlays
* fix(config): guard Foundry timeout overlays
* fix(config): normalize bundled provider overlays
* fix(models): reject overlay-only fallback models
Summary:
- The PR updates WhatsApp inbound listener and group-drop diagnostics, adds focused tests, and documents that observed but unregistered groups must be admitted through `channels.whatsapp.groups`.
- Reproducibility: yes. from source inspection: current main still emits the DM-only startup log and vague gro ... sions/whatsapp/src/auto-reply/monitor.ts` and `extensions/whatsapp/src/auto-reply/monitor/group-gating.ts`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(whatsapp): clarify group drop guidance
- PR branch already contained follow-up commit before automerge: fix(whatsapp): make inbound diagnostics policy-aware
- PR branch already contained follow-up commit before automerge: fix(whatsapp): clarify inbound group diagnostics
Validation:
- ClawSweeper review passed for head 0da24e3bbb.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0da24e3bbb
Review: https://github.com/openclaw/openclaw/pull/83969#issuecomment-4484218945
Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR clears the cached CLI config snapshot promise when a read rejects, adds a reject-retry-cache regression test, and adds an Unreleased changelog entry.
- Reproducibility: yes. Current main clearly caches the first snapshot-read promise, and the source PR supplied a focused reject, recover, cached-success probe; I did not rerun it in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: retry config snapshot after rejection
Validation:
- ClawSweeper review passed for head a46b5ec5c7.
- Required merge gates passed before the squash merge.
Prepared head SHA: a46b5ec5c7
Review: https://github.com/openclaw/openclaw/pull/83944#issuecomment-4484051060
Co-authored-by: honor2030 <19909783+honor2030@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Skip embedded-run wake/steer attempts for dormant completion requesters and keep late subagent completions on the requester-agent/direct handoff path.\n\nAlso records the missing regression assertion that dormant completion requesters do not call queueEmbeddedPiMessageWithOutcome and adds the maintainer changelog entry.\n\nVerification:\n- node scripts/run-vitest.mjs src/agents/subagent-announce-delivery.test.ts\n- git diff --check\n- Codex autoreview via local Copilot endpoint: no actionable regressions\n- CI on 0108ebb2b3: clean
Summary:
- Adds `OPENCLAW_IMAGE_PIP_PACKAGES` as an opt-in Dockerfile build arg, passes it through Docker and Podman local setup, and documents/tests the new local image-build option.
- Reproducibility: not applicable. this is an additive Docker/Podman build capability, not a bug report. The s ... image importing requested Python packages, and the branch diff wires the renamed arg through Docker/Podman.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docker: support optional pip packages in local builds
Validation:
- ClawSweeper review passed for head 0ccec19206.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0ccec19206
Review: https://github.com/openclaw/openclaw/pull/83850#issuecomment-4483676614
Co-authored-by: Stephen Redmond <stephen.redmond@straiteis.ie>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR changes queued reply followups so user_request items no longer carry or inherit a source abort signal, preserves room_event abort signals, adds focused regression coverage, and updates CHANGELOG.md.
- Reproducibility: yes. at source level. Current main attaches and later falls back to opts.abortSignal for qu ... ore-fix regression failures for the two implicated paths; I did not execute tests in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Preserve queued Telegram topic followups
Validation:
- ClawSweeper review passed for head 96fa0f69ba.
- Required merge gates passed before the squash merge.
Prepared head SHA: 96fa0f69ba
Review: https://github.com/openclaw/openclaw/pull/83827#issuecomment-4483451436
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch fixes Telegram forum-topic session routing, per-topic text/media buffering, media-group scoping, and outbound group send fairness, with focused Telegram regression tests and a changelog entry.
- Reproducibility: yes. source inspection of current main plus the PR body's before-proof give a high-confiden ... s_forum can collapse to the base group route, and global text/media buffer chains serialize sibling topics.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Fix Telegram forum topic parallel flow
Validation:
- ClawSweeper review passed for head b0f78fa275.
- Required merge gates passed before the squash merge.
Prepared head SHA: b0f78fa275
Review: https://github.com/openclaw/openclaw/pull/83829#issuecomment-4483486851
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* Improve Telegram groups config diagnostics
Add targeted guidance when channels.telegram.groups uses a non-object shape so startup/config validation and doctor explain the required group-id object map and topic nesting.
* fix(config): keep channel validation hints generic
* codex: surface deferred dynamic tool names
* codex: keep prompt snapshots source-backed
* style: wrap mac voice settings help text
* style: satisfy swiftformat for voice wake help text
* style: apply swiftformat to voice wake help text
* test: load codex prompt snapshots through plugin aliases
* test: type codex source surface loader
* test: avoid extra codex loader suppression
---------
Co-authored-by: pashpashpash <nik@vault77.ai>
Summary:
- The PR feeds loopback-scoped MCP tools into CLI system prompts and reports, persists a prompt tool-name hash for CLI session reuse, adds regression tests, and adds a changelog entry.
- Reproducibility: yes. from source inspection: current main builds the CLI prompt and report with `tools: []` ... execute a live CLI turn in this read-only review, but the source path and source PR terminal proof line up.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): gate prompt loopback tools on active runtime
- PR branch already contained follow-up commit before automerge: fix(cli): include loopback tools in cli prompts
Validation:
- ClawSweeper review passed for head d196564d4d.
- Required merge gates passed before the squash merge.
Prepared head SHA: d196564d4d
Review: https://github.com/openclaw/openclaw/pull/83828#issuecomment-4483469332
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR changes the Control UI chat delete confirmation popover from absolute above-trigger positioning to fixed viewport-clamped placement with focused geometry tests and a changelog entry.
- Reproducibility: yes. The related delete-click report maps directly to current main code that appends an abo ... able chat thread without viewport measurement; I did not run a live browser repro in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ui): keep delete confirm in viewport
Validation:
- ClawSweeper review passed for head bc000c5b64.
- Required merge gates passed before the squash merge.
Prepared head SHA: bc000c5b64
Review: https://github.com/openclaw/openclaw/pull/83825#issuecomment-4483439624
Co-authored-by: Thiago Costa <71539514+ThiagoCAltoe@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch narrows Memory Wiki imported-source `FsSafeError` wrapping, adds directory-collision bridge regressions, and adds a changelog entry crediting the source PR.
- Reproducibility: yes. Source inspection shows current main catches all imported-source `FsSafeError`s with symlink wording, and the linked source PR includes live bridge-sync output for the directory-collision path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(memory-wiki): normalize source page stat guard
- PR branch already contained follow-up commit before automerge: fix(memory-wiki): preserve fs-safe write diagnostics
Validation:
- ClawSweeper review passed for head e38ae3b998.
- Required merge gates passed before the squash merge.
Prepared head SHA: e38ae3b998
Review: https://github.com/openclaw/openclaw/pull/83839#issuecomment-4483591199
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds a personal-agent QA-Lab no-fake-progress scenario, registers it in the personal-agent pack, teaches mock-openai the scripted path, and updates focused tests, docs, and changelog.
- Reproducibility: not applicable. This PR adds QA coverage rather than reporting a current-main bug; the branch supplies concrete after-patch QA-Lab/mock-openai commands and copied pass output.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(qa-lab): add personal no-fake-progress scenario
Validation:
- ClawSweeper review passed for head 95d2e46288.
- Required merge gates passed before the squash merge.
Prepared head SHA: 95d2e46288
Review: https://github.com/openclaw/openclaw/pull/83824#issuecomment-4483439200
Co-authored-by: Firas Alswihry <itzfiras@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The replacement PR adds a `watch-targets` skills snapshot invalidation when `ensureSkillsWatcher` rebuilds f ... root set, reads the snapshot version after watcher setup, adds regression tests, and updates the changelog.
- Reproducibility: yes. Source inspection shows current main rebuilds the skills watcher on changed root targe ... the version before watcher setup; I did not run a live Gateway mount reproduction in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(skills): refresh snapshots when watch roots change
Validation:
- ClawSweeper review passed for head 2677dcc35a.
- Required merge gates passed before the squash merge.
Prepared head SHA: 2677dcc35a
Review: https://github.com/openclaw/openclaw/pull/83823#issuecomment-4483425019
Co-authored-by: hclsys <hclsys@openclaw.ai>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch changes memory-core fallback vector search to scan chunks in 256-row rowid batches with `setImmediate` yields, updates regression tests, and adds a changelog entry.
- Reproducibility: yes. from source and supplied live output. Current main synchronously scans fallback vector ... and the PR body shows the before/after heartbeat behavior through the actual `searchVector` fallback path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(memory-core): add boundary, parity, and concurrent-insert covera…
- PR branch already contained follow-up commit before automerge: fix(memory-core): yield event loop during fallback vector search (#81…
Validation:
- ClawSweeper review passed for head 0ede3d7168.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0ede3d7168
Review: https://github.com/openclaw/openclaw/pull/83758#issuecomment-4482137790
Co-authored-by: NW <nitinwadhawan66@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds Anthropic Claude 4.x image-capability normalization for stale text-only resolved model rows, regression tests for provider and fallback model resolution, and a changelog entry.
- Reproducibility: yes. for source-level reproduction: current main gates native images on model.input includi ... s text-only. I did not run the command locally because this review was constrained to read-only inspection.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(anthropic): preserve Claude image capability
Validation:
- ClawSweeper review passed for head 06dd378ea3.
- Required merge gates passed before the squash merge.
Prepared head SHA: 06dd378ea3
Review: https://github.com/openclaw/openclaw/pull/83756#issuecomment-4482116499
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR changes outbound channel registry loading and bootstrap to fall back from pinned setup-only channel entries to the active runtime registry, with regression tests and a changelog entry.
- Reproducibility: yes. at source level. Current main can select a pinned setup-only channel entry and skip th ... module live output showing delivery after the fallback; I did not run local tests in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(outbound): resolve send-capable channel registry
Validation:
- ClawSweeper review passed for head 67c20aa72b.
- Required merge gates passed before the squash merge.
Prepared head SHA: 67c20aa72b
Review: https://github.com/openclaw/openclaw/pull/83733#issuecomment-4481084888
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- This PR removes the WebChat special-case from auto-reply chunk limit/mode resolution, adds WebChat override regression tests, and records the fix in the changelog.
- Reproducibility: yes. from source inspection rather than runtime execution: current main returns the fallbac ... bchat` before reading `cfg.channels`, so a configured `channels.webchat.textChunkLimit` cannot take effect.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(auto-reply): honor webchat textChunkLimit/chunkMode config overri…
Validation:
- ClawSweeper review passed for head cd9ac01a36.
- Required merge gates passed before the squash merge.
Prepared head SHA: cd9ac01a36
Review: https://github.com/openclaw/openclaw/pull/83742#issuecomment-4481570742
Co-authored-by: luyao618 <364939526@qq.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR routes `session.tool` Gateway frames through the Control UI tool-stream handler, adds a regression test, and adds a changelog entry.
- Reproducibility: yes. Current main emits `session.tool` frames for session subscribers, but the Control UI d ... to the tool-stream handler, so the failure path is source-reproducible without needing a live browser run.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ui): render session-scoped tool events
Validation:
- ClawSweeper review passed for head 58be438acb.
- Required merge gates passed before the squash merge.
Prepared head SHA: 58be438acb
Review: https://github.com/openclaw/openclaw/pull/83734#issuecomment-4481086608
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- Adds a personal-agent QA-Lab share-safe diagnostics scenario with mock-openai support, pack registration/tests, docs, and changelog coverage.
- Reproducibility: not applicable. This PR adds a new QA-Lab scenario rather than fixing a current-main bug. T ... ce PR provides a clear after-patch validation path using qa-channel, a real gateway child, and mock-openai.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 46eb0af9e4.
- Required merge gates passed before the squash merge.
Prepared head SHA: 46eb0af9e4
Review: https://github.com/openclaw/openclaw/pull/83717#issuecomment-4480393933
Co-authored-by: Firas Alswihry <itzfiras@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR passes the effective OpenAI/Codex auth provider set into `/models` provider-header labeling, adds focused regression tests, and records the user-facing fix in the changelog.
- Reproducibility: yes. Current main lacks `acceptedProviderIds` in the shared picker header path, and the source PR's Mantis baseline/candidate proof shows the visible Telegram header mismatch and after-fix OAuth label.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(models): label picker auth via effective provider order
Validation:
- ClawSweeper review passed for head 8ca2924adc.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8ca2924adc
Review: https://github.com/openclaw/openclaw/pull/83726#issuecomment-4480805713
Co-authored-by: Stellar鱼 <2182712990@qq.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR changes collect-mode follow-up queue routing so unresolved-origin items can batch with a single resolved route and later compatible items can resume batching after a true cross-channel drain.
- Reproducibility: yes. at source level: current main treats unkeyed-plus-same-keyed queue items as cross-chan ... failing path is directly visible in `src/utils/queue-helpers.ts` and `src/auto-reply/reply/queue/drain.ts`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into maint-83701-20260518
Validation:
- ClawSweeper review passed for head e6ad029e23.
- Required merge gates passed before the squash merge.
Prepared head SHA: e6ad029e23
Review: https://github.com/openclaw/openclaw/pull/83701#issuecomment-4479943100
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds raw explicit-port detection for browser CDP URLs, updates profile resolution precedence, adds regression tests, and records the browser fix in the changelog.
- Reproducibility: yes. Source inspection shows current main resolves a portless profile `cdpUrl` through `par ... 443, and overwrites the configured `cdpPort`; the source PR also provides live before/after Chrome output.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(browser): encapsulate explicit-port detection in parseBrowserHttpUrl
- PR branch already contained follow-up commit before automerge: fix(browser): preserve explicit cdpPort when cdpUrl omits port
Validation:
- ClawSweeper review passed for head 070c31cdcf.
- Required merge gates passed before the squash merge.
Prepared head SHA: 070c31cdcf
Review: https://github.com/openclaw/openclaw/pull/83707#issuecomment-4480058057
Co-authored-by: Hongwei Ma <marvae24@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch restricts exact-head ClawSweeper proof markers to GitHub App-authored comments, adds read-only issue-comment token fallback for the proof workflow, and adds focused regression tests plus a changelog entry.
- Reproducibility: yes. Source inspection of current main shows any issue comment body with a matching `clawsw ... SHA is accepted without author/App authentication; the PR adds focused negative tests for forged comments.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ci): authenticate proof verdict markers
Validation:
- ClawSweeper review passed for head f4c375eaa7.
- Required merge gates passed before the squash merge.
Prepared head SHA: f4c375eaa7
Review: https://github.com/openclaw/openclaw/pull/83692#issuecomment-4479843682
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The branch adds `openclaw browser evaluate --timeout-ms`, forwards it to the evaluate body and request timeo ... ents and tests it, adds a changelog entry, and includes a config.patch no-op shortcut from the repair pass.
- Reproducibility: not applicable. this is a feature PR rather than a bug report. Source inspection shows current main lacks the CLI flag while the branch wires it into an already-supported evaluate `timeoutMs` payload.
Automerge notes:
- PR branch already contained follow-up commit before automerge: feat(browser): add evaluate timeout CLI option
Validation:
- ClawSweeper review passed for head 0d81d3d93e.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0d81d3d93e
Review: https://github.com/openclaw/openclaw/pull/83696#issuecomment-4479900502
Co-authored-by: fred <fengruifree@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR removes the Control UI chat fallback that converts a null stream into an empty stream for abortable runs, adds null-vs-empty stream regression tests, and updates the changelog.
- Reproducibility: yes. source-level reproduction is high confidence: current main converts null stream plus c ... ading indicator. The linked source PR also reports live Control UI verification after the equivalent patch.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(ui): prevent reading indicator from sticking after assistant resp…
Validation:
- ClawSweeper review passed for head 44bea55110.
- Required merge gates passed before the squash merge.
Prepared head SHA: 44bea55110
Review: https://github.com/openclaw/openclaw/pull/83711#issuecomment-4480128171
Co-authored-by: 二狗子 <njuboy11@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- Adds `--global` to `openclaw skills install` and `openclaw skills update`, routing ClawHub installs and updates to the shared managed skills root with docs, changelog, and CLI command tests.
- Reproducibility: not applicable. as a bug reproduction; this is a new CLI feature request. Source inspection confirms current `main` lacks `--global`, and the source PR includes after-fix terminal proof for the new path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): address skills global review
- PR branch already contained follow-up commit before automerge: feat(cli): support installing skills to shared global directory via -…
Validation:
- ClawSweeper review passed for head 6eb7187fc1.
- Required merge gates passed before the squash merge.
Prepared head SHA: 6eb7187fc1
Review: https://github.com/openclaw/openclaw/pull/83705#issuecomment-4480023577
Co-authored-by: Hongwei Ma <marvae24@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR makes skill-creator quick validation reject empty or whitespace-only `name` and `description` fields, adds regression tests, and records the fix in the changelog.
- Reproducibility: yes. Source inspection on current main shows empty or whitespace-only values skip validation after `.strip()`, and the source PR includes before/after terminal output for the same path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(skill-creator): reject empty name and description in skill valida…
Validation:
- ClawSweeper review passed for head 0fb4555cb2.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0fb4555cb2
Review: https://github.com/openclaw/openclaw/pull/83704#issuecomment-4479984760
Co-authored-by: jay <a1@ponys-Mac.local>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- Adds a symptom-keyed troubleshooting block to `docs/gateway/config-channels.md` for group/channel @mentions that log `queuedFinal=false, replies=0` and explains the `visibleReplies` remedies.
- Reproducibility: yes. for the docs gap and source behavior: current main lacks the exact symptom-keyed troubleshooting entry, and the resolver/tests show when message-tool mode suppresses automatic final delivery.
Automerge notes:
- PR branch already contained follow-up commit before automerge: docs(gateway): make group reply fix restart conditional
- PR branch already contained follow-up commit before automerge: docs(gateway): qualify direct-chat reply default in troubleshooting
- PR branch already contained follow-up commit before automerge: docs(gateway): align group reply troubleshooting with current automat…
- PR branch already contained follow-up commit before automerge: docs(gateway): scope group reply suppression cause to group config
Validation:
- ClawSweeper review passed for head e60ae89b20.
- Required merge gates passed before the squash merge.
Prepared head SHA: e60ae89b20
Review: https://github.com/openclaw/openclaw/pull/77052#issuecomment-4367898048
Co-authored-by: yetval <yetvald@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR removes the empty `mkdirSync({ recursive: true })` catch in the memory host SDK `ensureDir()`, adds a regression test for surfaced mkdir failures, and adds a changelog entry.
- Reproducibility: yes. from source inspection rather than a locally executed repro. Current main swallows eve ... kdir failure in `ensureDir()`, and the active memory database path calls that helper before opening SQLite.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 0f82f185cc.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0f82f185cc
Review: https://github.com/openclaw/openclaw/pull/41259#issuecomment-4326310101
Co-authored-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates the skills CLI formatter, tests, and changelog so `skills info` resolves case-insensitive and ... ator-normalized skill name variants only when non-exact matches are unique, and sanitizes not-found output.
- Reproducibility: yes. by source inspection. The documented `openclaw skills info <name>` command passes the ... ormatter lookup on current main, while skill status entries can have distinct `name` and `skillKey` values.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(skills): exercise case-insensitive lookup branch
- PR branch already contained follow-up commit before automerge: style(skills): format lookup resolver signature
- PR branch already contained follow-up commit before automerge: fix(skills): sanitize not-found output and avoid ambiguous lookup mat…
- PR branch already contained follow-up commit before automerge: fix(skills): require unique case-insensitive info matches
Validation:
- ClawSweeper review passed for head 01f3e2d468.
- Required merge gates passed before the squash merge.
Prepared head SHA: 01f3e2d468
Review: https://github.com/openclaw/openclaw/pull/38713#issuecomment-4321021300
Co-authored-by: NewdlDewdl <rohin.agrawal@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds highlight.js-backed WebChat code-block highlighting, scoped token CSS, regression tests, a type shim, and a direct UI dependency.
- Reproducibility: not applicable. as a bug reproduction; this is a feature addition. The feature gap is source-evident because current main renders code blocks as escaped plaintext without hljs token markup.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 7bb95c47ed.
- Required merge gates passed before the squash merge.
Prepared head SHA: 7bb95c47ed
Review: https://github.com/openclaw/openclaw/pull/83569#issuecomment-4476990135
Co-authored-by: zhengzuo0-ai <zheng.zuo0@gmail.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates the memory-wiki `wiki_lint` tool to show vault-relative lint report paths in tool text and details, keeps the core linter/CLI result absolute, adds regression coverage, and adds a changelog entry.
- Reproducibility: yes. there is a high-confidence source reproduction path: current main returns the linter's ... tPath` in `wiki_lint` text and raw details. I did not execute the harness because this review is read-only.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(memory-wiki): make wiki_lint tool output path-safe
Validation:
- ClawSweeper review passed for head df5c7db151.
- Required merge gates passed before the squash merge.
Prepared head SHA: df5c7db151
Review: https://github.com/openclaw/openclaw/pull/83687#issuecomment-4479682214
Co-authored-by: LLagoon3 <choonarm3@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
* ci(proof): trust maintainer label for private org members
Private organization memberships report author_association=CONTRIBUTOR
on PRs, so the real-behavior-proof gate currently demands proof from
maintainers whose membership is private. The labeler workflow already
applies the 'maintainer' label via the team-membership API (which sees
private members), so treat that label as an equivalent privileged
signal in evaluateRealBehaviorProof.
* ci(proof): drop noisy comments
* ci(proof): check maintainer team membership via GitHub App token
Replace the label-based private-maintainer skip with a direct
getMembershipForUserInOrg call using a minted GitHub App token, mirroring
the pattern labeler.yml already uses for the same lookup. Removes the
race against the labeler workflow and the implicit dependency on the
'maintainer' label having landed first.
The App-token steps are continue-on-error so the gate still runs (using
the existing author_association path) when the App key secrets are
absent or both mints fail.
* ci(proof): narrow App token to members:read
ClawSweeper review #83418: actions/create-github-app-token defaults to
the full installation permission set, but the proof gate only needs the
org-members read scope used by teams.getMembershipForUserInOrg. Set
permission-members: read on both the primary and fallback mint steps.
* docs(changelog): private maintainers skip the real-behavior-proof gate
Summary:
- The branch updates the transcript tail assistant reader to skip trailing non-message rows, adds cache-ttl gap-fill regression tests, and adds a changelog entry.
- Reproducibility: yes. Source inspection shows cache-ttl custom rows can sit after the canonical assistant me ... r stops on that row; the PR body also supplies a concrete live three-turn CLI reproduction after the patch.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(transcript): skip trailing custom entries in tail assistant reade…
Validation:
- ClawSweeper review passed for head 866aa27ca8.
- Required merge gates passed before the squash merge.
Prepared head SHA: 866aa27ca8
Review: https://github.com/openclaw/openclaw/pull/83635#issuecomment-4478637780
Co-authored-by: yaoyi1222 <yaoyi_1222@163.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Summary:
- The PR updates cron timer task-run creation to derive `childSessionKey` for isolated agent-turn jobs from the stable cron session key, adds focused timer coverage, and records the fix in the changelog.
- Reproducibility: yes. Current main's timer task creation copies only `job.sessionKey`, while isolated cron e ... Id>:cron:<jobId>` later; the supplied before-test output matches that source path by receiving `undefined`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cron): link isolated task runs to cron session
Validation:
- ClawSweeper review passed for head 748998b018.
- Required merge gates passed before the squash merge.
Prepared head SHA: 748998b018
Review: https://github.com/openclaw/openclaw/pull/83606#issuecomment-4478039217
Co-authored-by: Jai Govindani <jai.g@ewa-services.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Follow-up and main reply paths re-entered each embedded fallback candidate
with the same queued transcript prompt. After the first candidate persisted
that queued user message, later candidates appended it again. Failed
embedded candidates could also persist an assistant error stub on each
retry, leaving same-role transcript runs that downstream providers reject.
The fallback callers now keep two persistence latches for one fallback run:
queuedUserMessagePersistedAcrossFallback flips from onUserMessagePersisted,
and assistantErrorPersistedAcrossFallback flips only after the session guard
actually persists an assistant stopReason="error" message. Later candidates
suppress only the entries that were already written, so CLI or otherwise
non-persisting failures do not hide the first embedded error separator.
Plumb the assistant-error persistence callback through the embedded runner,
attempt params, and session guard wrapper. Add guard and runner regression
tests for all-embedded fallback retries and CLI-to-embedded fallback.
Closes#83404
Clear stale CLI provider resume bindings when a normal gateway session is reset, while preserving spawned subagent bindings.
Also isolate target normalization in the outbound source-delivery unit test so the CI shard does not load provider/plugin runtime state for a pure matcher case.
Co-authored-by: psyphix-claw <262498103+psyphix-claw@users.noreply.github.com>
Keep QMD-exported archived session transcript hits visible by resolving QMD `.md` archive stems back to their live session ids before applying session visibility policy. Preserve normal markdown session ids that only resemble archive names, reject ambiguous slug fallback matches, and keep deleted same-agent QMD archives readable when the live store entry is gone.
Fixes#83506.
Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com>
Fixes#83388.
- Honor per-agent `tools.codeMode` in config schema, runtime code-mode resolution, and model payload filtering.
- Preserve grouped OpenAI tool declarations when code-mode filtering keeps only `exec` and `wait`.
- Sync generated config/prompt baselines and carry a narrow media CI unblocker from current `main` fallout.
Co-authored-by: Kaspre <kaspre@gmail.com>
feat(docker): add image apt package build arg
Add OPENCLAW_IMAGE_APT_PACKAGES as the preferred runtime-neutral image build arg for Docker and Podman apt package installs while keeping OPENCLAW_DOCKER_APT_PACKAGES as the legacy fallback.
Maintainer verification:
- pnpm docs:list
- node scripts/run-vitest.mjs run --config test/vitest/vitest.e2e.config.ts src/docker-setup.e2e.test.ts
- node scripts/run-vitest.mjs src/dockerfile.test.ts test/scripts/test-install-sh-docker.test.ts
- node scripts/run-vitest.mjs run --config test/vitest/vitest.cron.config.ts src/cron/isolated-agent.model-overrides.test.ts
- pnpm exec oxfmt --check --threads=1 docs/install/docker.md docs/install/podman.md scripts/clawdock/README.md docs/help/faq.md CHANGELOG.md
- git diff --check origin/main...HEAD
- .agents/skills/autoreview/scripts/autoreview --mode local
- .agents/skills/autoreview/scripts/autoreview --mode branch
- pnpm check:changed via Blacksmith Testbox tbx_01krwqmfhcdekaczvrkxnb7t59, Actions run 26014630478, exit 0
Known CI note: checks-node-core-runtime-shared timed out repeatedly in unrelated src/cron/isolated-agent.model-overrides.test.ts on GitHub Actions; the same test passes locally after this rebase.
Co-authored-by: Said Urtabajev <said@bumpclub.ee>
Treat Telegram HTTP 421 / Misdirected Request responses as retryable transport failures in both the default channel API retry policy and the strict outbound send retry path.
Wire the 421 handling into isSafeToRetrySendError so non-idempotent Telegram send operations can retry this edge-node rejection without enabling broad ambiguous network retries, and add regression coverage for the default retry path plus strict send predicate handling.
* fix(doctor): archive legacy clawd browser profile residue
* Avoid browser cleanup load without residue
Doctor --fix now skips loading the browser doctor facade unless the legacy browser/clawd profile path exists, preventing broad config repair tests from paying the plugin load cost when there is nothing to archive.
* Use structured health check for browser residue
Register the legacy clawd browser profile residue cleanup through the modern doctor health-check contract so doctor --lint can report it and doctor --fix repairs it through structured effects.
Summary
Problem: root CHANGELOG.md updates currently cause broad pull request and push workflow activity, including CI and workflow sanity fanout, even though changelog-only edits do not touch product, runtime, docs site, or workflow logic.
Why it matters: the PR workflow (review, prepare, and land) can add or adjust CHANGELOG.md entries while processing otherwise-ready PRs. Those changelog-only updates retrigger gates, delay landing, and create avoidable contention when several PRs are being landed close together.
What changed: CI now ignores pull requests whose only changed path is CHANGELOG.md; Workflow Sanity ignores changelog-only pull requests and main-branch pushes; Docs keeps its markdown/docs trigger but excludes root CHANGELOG.md from the push path set.
What did NOT change (scope boundary): metadata-only automation such as labelers, auto-response, real behavior proof, or external GitHub apps can still run on PR events because those workflows are event-driven rather than file-scope CI. Other markdown files, docs files, and workflow files still trigger their existing checks.
OAuth login flow
----------------
- Hard-require refresh_token after the authorization-code exchange in
xai-oauth.ts. Access-only responses persisted credentials that the
downstream usability check later rejected; the new requireRefreshToken
option fails the exchange instead. Error wording explains the missing
refresh_token in OIDC scope terms (offline_access scope rejected),
not a "grant".
- Derive token expiry from the access-token JWT exp claim when
expires_in is missing. id_token exp is intentionally not used as a
fallback because id_token lifetime tracks the OIDC session, not the
access token, and would defer refresh past actual expiry.
- Handle CORS preflight OPTIONS on the loopback OAuth callback in
src/plugin-sdk/provider-auth-runtime.ts. The previous handler treated
any non-callback request as a failed GET, returned "Missing code or
state", and tore the server down before the real GET arrived. The
CORS allowlist is now an optional `corsOriginAllowlist` parameter on
waitForLocalOAuthCallback so the SDK helper stays generic. The xAI
plugin passes ["auth.x.ai", "accounts.x.ai"] from loginXaiOAuth.
Sidecar surfaces
----------------
- speech-provider.ts (POST /v1/tts) honors the xAI OAuth profile in
addition to provider config and XAI_API_KEY. isConfigured now also
reports true when an xAI auth profile is configured (via
isProviderAuthProfileConfigured), so OAuth-only users are no longer
silently filtered out by the selection layer. The bearer resolver
threads req.cfg into resolveApiKeyForProvider so the right xAI auth
profile is picked when a user has multiple.
- realtime-transcription-provider.ts (WSS /stt) gets the same
isConfigured fix, and the lazy headers() resolver threads req.cfg
into the OAuth bearer lookup. createSession stays sync per its
plugin contract.
- stt.ts: drop the plugin-side OAuth fallback. The media-understanding
core already resolves auth (cfg/agentDir-aware) via
resolveProviderExecutionContext before calling transcribeAudio, so
the wrapper was redundant. transcribeAudio is now the registered
hook directly.
User-Agent attribution
----------------------
- New buildXaiAttributionPolicy in src/agents/provider-attribution.ts
injects User-Agent: openclaw/<version>, originator, and version on
/v1/responses and /v1/chat/completions traffic that goes through
resolveProviderRequestHeaders. Gated to xai-native and default
endpoint classes; custom proxy baseUrls remain withheld. reviewNote
is honest about which headers are spec-verified vs mirrored.
- Shared extensions/xai/src/xai-user-agent.ts helper exports
xaiUserAgentHeaderFor(baseUrl) which only emits the User-Agent when
the resolved baseUrl points at the xAI-native API host. Threaded
through TTS and realtime STT (WS upgrade headers) so user-configured
proxy baseUrls do not receive the openclaw identity. OAuth discovery
and token endpoints still send User-Agent unconditionally because
isTrustedXaiOAuthEndpoint already restricts those URLs to *.x.ai.
- Image gen, batch STT, and video gen rely on the attribution policy
alone (no manual User-Agent in defaultHeaders), so attribution
withholding on user-configured proxy baseUrls is preserved
end-to-end.
- UA is bearer-agnostic: same value whether the bearer comes from an
xAI API key or the xAI OAuth flow.
Drop dead api.grok.x.ai alias
-----------------------------
- xAI retired the api.grok.x.ai alias; DNS now returns NXDOMAIN from
xAI's own authoritative nameservers. Drop it from the xai-native
endpoint host set in extensions/xai/openclaw.plugin.json,
extensions/xai/api.ts, extensions/xai/tts.ts, and the
openai-responses payload policy. Update the attribution test to
classify api.grok.x.ai as "custom" (no live user can reach it; the
classification keeps documenting the host's status).
Video generation now matches xAI's actual API behavior
------------------------------------------------------
Previously, real video generation requests failed with
"xAI video generation response malformed" because the poll-status
handler validated against a closed enum that did not match what the
xAI service actually returns. Four fixes:
- Loosen the poll-status handler. xAI returns intermediate strings
outside `["queued", "processing", "done", "failed", "expired"]`
(commonly `submitted`, `pending`, `in_progress`, ...). Treat `done`
as terminal-success, `["failed", "error", "expired", "cancelled"]`
as terminal-failure, and any other string (including empty) as
continue-polling. Also accept `cancelled` as a terminal failure.
- Send default duration/aspect_ratio/resolution on every generate and
reference-image submit. xAI rejects bodies that omit these fields.
Defaults: duration=8s, aspect_ratio="16:9", resolution="720p".
- Accept lowercase resolution input ("480p"/"720p"/"1080p") in
addition to uppercase, normalize to lowercase on the wire.
- Add an `x-idempotency-key` header (fresh `crypto.randomUUID()`) on
every submit so a network retry does not double-charge the user.
Polls intentionally reuse the unmodified `headers` without the key.
Ergonomics
----------
- All "missing xAI credentials" errors (code_execution, lazy
code_execution fallback in extensions/xai/index.ts, x_search,
web_search grok in web-search-provider.runtime.ts, TTS, batch STT,
realtime STT) now mention `openclaw onboard --auth-choice xai-oauth`
first.
- Dedupe the Grok model-id alias table: model-compat.ts re-exports
normalizeXaiModelId from model-id.ts as normalizeNativeXaiModelId.
Test coverage
-------------
- src/plugin-sdk/provider-auth-runtime.test.ts: locks the new pure
buildOAuthCallbackOriginResolver gate (allowlist match,
case-normalization, https-only, non-allowlisted hosts dropped,
multi-Origin handling).
- extensions/xai/xai-oauth.test.ts: locks
XAI_OAUTH_CALLBACK_CORS_ORIGIN_ALLOWLIST so loginXaiOAuth keeps
threading the right hosts to the SDK helper.
- extensions/xai/speech-provider.test.ts: OAuth-only auth profile
flips isConfigured to true; cfg threads into the OAuth fallback
resolver.
- extensions/xai/realtime-transcription-provider.test.ts: same +
upgrade headers carry the OAuth bearer end-to-end.
- extensions/xai/stt.test.ts: explicit assertion that transcribeAudio
trusts the core-resolved apiKey (no plugin-side wrapper).
Verification
------------
- pnpm install: clean
- 154/154 vitest tests pass across 13 touched test files
- pnpm check:changed: typecheck core/ext + tests, oxlint core/ext,
runtime guards, dependency pin guard, package patch guard, runtime
import cycles, sidecar loader guard - all green
- pnpm build: 0 errors, 0 [INEFFECTIVE_DYNAMIC_IMPORT] warnings
Add core and hook mapper regression coverage for the thread-origin contract behind #83302.\n\nThe tests prove a flat reply target can coexist with a thread-addressable OriginatingTo, and hook canonical conversation mapping keeps following OriginatingTo.\n\nProof: focused Vitest, autoreview, Testbox check:changed tbx_01krwaztbwm13sx9e4sbyyz4c1, and CI run 26008670388 passed.
Fix Telegram forum-topic OriginatingTo routing for inbound, audio-preflight, and skipped-message hook contexts.
Centralize Telegram inbound origin target construction so real forum topics stay encoded in the routing target while DM thread ids remain metadata-only.
Fixes#83302.
Summary:
- The PR changes Discord reply delivery, sanitizer, and queued follow-up auto-reply paths so explicit verbose tool-progress payloads are delivered while final assistant replies still use the privacy sanitizer.
- Reproducibility: yes. source-level: current main strips tool-looking Discord payload text at the front-chann ... ds compaction events in queued follow-up runs. I did not run a live Discord repro in this read-only review.
Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix: gate queued follow-up progress when verbose is off
- Included post-review commit in the final squash: fix: preserve queued verbose progress under preview suppression
- Included post-review commit in the final squash: ci: rerun discord verbose progress PR
- Included post-review commit in the final squash: fix: preserve Discord verbose progress after rebase
- Included post-review commit in the final squash: fix: serialize discord queued progress
- Included post-review commit in the final squash: Fix Discord verbose tool progress delivery
Validation:
- ClawSweeper review passed for head fd845e773a.
- Required merge gates passed before the squash merge.
Prepared head SHA: fd845e773a
Review: https://github.com/openclaw/openclaw/pull/80042#issuecomment-4414121881
Co-authored-by: Clawsistant <clawsistant@users.noreply.github.com>
Co-authored-by: anyech <anyech@gmail.com>
Co-authored-by: OpenClaw Assistant <assistant@openclaw.local>
Co-authored-by: Shadow <hi@shadowing.dev>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: thewilloftheshadow
Co-authored-by: thewilloftheshadow <35580099+thewilloftheshadow@users.noreply.github.com>
Summary:
- The PR changes ordinary unmanaged gateway restarts to return the existing in-process fallback instead of detached-spawning a replacement child, with focused tests, docs wording, and a changelog entry.
- Reproducibility: yes. at source level: current main and v2026.5.12 detach-spawn unmanaged ordinary restarts, ... e PR body also supplies after-fix terminal proof that the patched helper returns disabled without spawning.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 8c82df6c77.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8c82df6c77
Review: https://github.com/openclaw/openclaw/pull/83138#issuecomment-4471071848
Co-authored-by: mjamiv <74088820+mjamiv@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds a generic inbound debounce `cancelKey`, uses Telegram stop-like controls to cancel same-chat pen ... buffers and bypass debounce, and adds focused Telegram regression coverage plus updated channel test mocks.
- Reproducibility: yes. by source inspection: current main enqueues Telegram text through inbound debounce bef ... nly has flush semantics for pending keyed work. I did not run a live Telegram repro in this read-only pass.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Fix Telegram stop debounce bypass
Validation:
- ClawSweeper review passed for head 19245a341d.
- Required merge gates passed before the squash merge.
Prepared head SHA: 19245a341d
Review: https://github.com/openclaw/openclaw/pull/83248#issuecomment-4472300906
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Refactor docs/plugins/building-plugins.md into the scoped plugin-author guide, preserving the legacy registering-agent-tools anchor and restoring the original Next steps section.
* feat(doctor): add --lint mode + structured HealthFinding shape
Adds the core machinery for `openclaw doctor --lint` per the
doctor-lint-and-oc-rules upstream proposal. PR-1 of the proposal:
no new top-level verb, no public plugin SDK; everything internal.
Files:
- src/flows/checks.ts ? HealthFinding / HealthCheck / HealthCheckContext
types. Findings carry severity per-finding; checks return
readonly HealthFinding[]. Mode tag (doctor/lint/fix) lets a check
distinguish the calling posture.
- src/flows/health-check-registry.ts ? module-level registry with
duplicate-id rejection + test reset helper.
- src/flows/doctor-lint-flow.ts ? runner over registered checks.
Catches throws into synthetic error findings (anchored at check id;
message scrubbed of control chars, capped at 256 bytes). Sorts
findings by severity desc, check id, path. Exports
exitCodeFromFindings (1 if any warning/error, 0 otherwise).
- src/flows/doctor-core-checks.ts ? 4 modern HealthChecks rewriting
logic from existing legacy run*Health functions:
core/doctor/gateway-config (warning)
core/doctor/command-owner (info)
core/doctor/workspace-status (info)
core/doctor/final-config-validation (error)
Each was audited safe per the proposal's adapter constraints
(no writes, no repair calls, no prompts, no probes incl. local-bind).
Legacy run*Health contributions in doctor-health-contributions.ts
are unchanged ? doctor mode (no --lint) still runs the existing 35.
- src/commands/doctor-lint.ts ? CLI dispatch for --lint. Reads config
snapshot, builds HealthCheckContext (mode: "lint"), runs the registry,
filters by --severity-min, emits human or JSON output, returns exit
code from unfiltered set so --severity-min hides info findings
without changing CI signal.
- src/cli/program/register.maintenance.ts ? adds --lint, --json,
--severity-min, --skip, --only flags to existing doctor command.
--lint branches to runDoctorLintCli; without --lint, doctor runs
unchanged.
LoC: 382 src across 6 files. Tests + doc + oc-path-side rule packs
follow as separate commits on this branch.
* fix: avoid string spread in doctor errors
* chore: refresh plugin SDK API baseline
* docs: clarify doctor lint usage
* feat(doctor): prepare repairs for dry-run reporting
* fix(doctor): detect stale session snapshot paths
Warn when cached session snapshot metadata still references bundled skill paths from inactive OpenClaw runtime roots, while keeping workspace skill roots and current runtime paths quiet.
* fix(doctor): honor configured session stores
* fix(doctor): scan raw snapshot paths
Expand home-relative cached snapshot paths before stale bundled-skill classification and scan raw session-store JSON so persisted resolvedSkills are inspected before normal session-store normalization strips them.
Summary:
- This PR adds a strict initial subagent registry persistence path, rolls back failed registrations, updates affected test seams, adds a regression test, and records the fix in the changelog.
- Reproducibility: yes. Source inspection on current main shows registry save failures are swallowed after the ... s added, and the linked source PR provides an ENOSPC-style after-fix terminal proof for the corrected path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(agents): persist subagent registry before returning accepted (#83…
Validation:
- ClawSweeper review passed for head d564ef051d.
- Required merge gates passed before the squash merge.
Prepared head SHA: d564ef051d
Review: https://github.com/openclaw/openclaw/pull/83238#issuecomment-4472173642
Co-authored-by: yetval <yetvald@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR buffers Codex command-output deltas per command item and uses them as a fallback for transcripts, trajectory output, final tool output, and after-tool-call errors when `aggregatedOutput` is empty.
- Reproducibility: yes. A source-level reproduction is clear: send current-turn command-output delta notificat ... aggregatedOutput: null`; current main has no final transcript or trajectory fallback for the streamed text.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(codex): preserve streamed command output
Validation:
- ClawSweeper review passed for head 07393a304f.
- Required merge gates passed before the squash merge.
Prepared head SHA: 07393a304f
Review: https://github.com/openclaw/openclaw/pull/83222#issuecomment-4472054629
Co-authored-by: 0x505badc0de <32790662+rozmiarD@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR exempts run-mode `cleanup: "keep"` subagent registry entries from the session-mode sweep TTL, adds focused regression coverage, and records the fix in the changelog.
- Reproducibility: yes. Current main source shows a run-mode keep entry has no `archiveAtMs` and then matches ... ; the linked source PR also provides before/after terminal proof against a real persisted `runs.json` path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(agents): preserve run-mode keep subagents past session sweep TTL …
Validation:
- ClawSweeper review passed for head 32faf5cf32.
- Required merge gates passed before the squash merge.
Prepared head SHA: 32faf5cf32
Review: https://github.com/openclaw/openclaw/pull/83226#issuecomment-4472073823
Co-authored-by: yetval <yetvald@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR replaces per-bar absolute Usage chart tooltips with one viewport-fixed floating tooltip and adds focus/keyboard handling plus focused jsdom coverage.
- Reproducibility: yes. at source level. Current main renders an absolute `.daily-bar-tooltip` inside `.daily- ... ` overflow contexts, and the linked issue plus PR before screenshot demonstrate the tall-bar clipping case.
Automerge notes:
- PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix-usage-tooltip-clipping
Validation:
- ClawSweeper review passed for head edbb26a5be.
- Required merge gates passed before the squash merge.
Prepared head SHA: edbb26a5be
Review: https://github.com/openclaw/openclaw/pull/82846#issuecomment-4468967811
Co-authored-by: sandypockets <41454557+sandypockets@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR updates the CLI post-update gateway recovery formatter and tests to show Linux, macOS, Windows, or generic service-manager guidance, plus a changelog entry.
- Reproducibility: yes. Source inspection gives a high-confidence reproduction path: current main reaches a fo ... hAgent recovery text, while the platform contract says Linux uses systemd and Windows uses Scheduled Tasks.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(update): tailor gateway recovery hints by platform
Validation:
- ClawSweeper review passed for head 0cf2a0c5a7.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0cf2a0c5a7
Review: https://github.com/openclaw/openclaw/pull/83191#issuecomment-4471471293
Co-authored-by: Rubén Cuevas <hi@rubencu.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
description: "Autoreview closeout: local dirty changes, PR branch vs main, parallel tests."
description: "Auto Review closeout. Codex review is the default when no engine is set and is the recommended reviewer."
---
# Autoreview
# Auto Review
Run Codex's built-in code review as a closeout check. This is code review (`codex review`), not Guardian `auto_review` approval routing.
Run the bundled structured review helper as a closeout check. This is code review, not Guardian `auto_review` approval routing.
Codex review is the default when no engine is set. It usually delivers the best review results and should remain the normal final closeout engine.
Use when:
- user asks for Codex review / autoreview / second-model review
- user asks for Codex review / Claude review / autoreview / second-model review
- after non-trivial code edits, before final/commit/ship
- reviewing a local branch or PR branch after fixes
@@ -19,12 +22,19 @@ Use when:
- Read dependency docs/source/types when the finding depends on external behavior.
- Reject unrealistic edge cases, speculative risks, broad rewrites, and fixes that over-complicate the codebase.
- Prefer small fixes at the right ownership boundary; no refactor unless it clearly improves the bug class.
- Keep going until the selected review path returns no accepted/actionable findings.
- If a review-triggered fix changes code, rerun focused tests and rerun the review helper.
-Default to Codex review. If Codex is unavailable or exits with an error, the helper may fall back to `claude -p`; `pi -p` and `opencode run` are explicit reviewer/fallback options. The helper runs nested Codex review in yolo/full-access mode by default; use `--no-yolo` only when intentionally testing sandbox behavior.
-Stop as soon as the review command/helper exits 0 with no accepted/actionable findings. Do not run an extra direct `codex review` just to get a nicer "clean" line, a second opinion, or clearer closeout wording.
- Keep going until structured review returns no accepted/actionable findings.
- If a review-triggered fix changes code, rerun focused tests and rerun the structured review helper.
-For security-audit suppression changes, verify accepted findings remain auditable: suppressed findings stay in structured output, active output keeps an unsuppressible suppression notice, and aggregate findings cannot hide unrelated active risk.
-Never switch or override the requested review engine/model. If the review hits model capacity, retry the same command a few times with the same engine/model.
- Tools are useful in review mode. The helper allows read-only inspection tools and web search by default so reviewers can check dependency contracts, upstream docs, and current behavior.
- Security perspective is always included, but it should not cripple legitimate functionality. Report security findings only when the change creates a concrete, actionable risk or removes an important safety check.
- Do not invoke built-in `codex review`, nested reviewers, or reviewer panels from inside the review. The helper builds one bundle, calls one selected engine, validates one structured result, and stops.
- Stop as soon as the helper exits 0 with no accepted/actionable findings. Do not run an extra review just to get a nicer "clean" line, a second opinion, or clearer closeout wording.
- Treat the helper's successful exit plus absence of actionable findings as the clean review result, even if the underlying Codex CLI output is terse.
- Multi-reviewer panels are opt-in only. Use them when explicitly requested or when risk justifies the extra spend; the main agent still verifies every accepted finding before fixing.
- If rejecting a finding as intentional/not worth fixing, add a brief inline code comment only when it explains a real invariant or ownership decision that future reviewers should know.
- If `gh`/Gitcrawl reports `database disk image is malformed`, run `gitcrawl doctor --json` once to let the portable cache repair before retrying review; do not bypass the shim unless repair fails and freshness requires live GitHub.
- If Gitcrawl reports a portable manifest mismatch, source/runtime DB health error, or stale portable-store checkout, run `gitcrawl doctor --json` and inspect `source_db_health`, `runtime_db_health`, and `portable_store_status` before falling back to live GitHub.
- Do not push just to review. Push only when the user requested push/ship/PR update.
## Pick Target
@@ -32,41 +42,44 @@ Use when:
Dirty local work:
```bash
codex review --uncommitted
<autoreview-helper> --mode local
```
Use this only when the patch is actually unstaged/staged/untracked in the
current checkout. For committed, pushed, or PR work, point Codex at the commit
current checkout. For committed, pushed, or PR work, point the helper at the commit
or branch diff instead; do not force `--mode local` / `--uncommitted` just
because the helper docs mention dirty work first. A clean `--uncommitted` review
because the helper docs mention dirty work first. A clean local review
Do not pass an inline prompt with `--base`; current CLI rejects `--base` + `[PROMPT]` even though help text is ambiguous. If custom instructions are needed, run the plain base review first, then do a local/manual follow-up pass.
.agents/skills/autoreview/scripts/autoreview --mode commit --commit HEAD
/Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview --mode commit --commit HEAD
```
Use commit review for already-landed or already-pushed work on `main`. Reviewing
@@ -79,50 +92,93 @@ with `--base`.
Format first if formatting can change line locations. Then it is OK to run tests and review in parallel:
```bash
.agents/skills/autoreview/scripts/autoreview --parallel-tests "<focused test command>"
scripts/autoreview --parallel-tests "<focused test command>"
```
Tradeoff: tests may force code changes that stale the review. If tests or review lead to code edits, rerun the affected tests and rerun review until no accepted/actionable findings remain. Once that rerun exits cleanly, stop; do not spend another long review cycle on redundant confirmation.
## Review Panels
Run multiple reviewers against one frozen bundle:
```bash
<autoreview-helper> --reviewers codex,claude
```
`--panel` is shorthand for Codex plus Claude unless `--engine` changes the first reviewer:
```bash
<autoreview-helper> --panel
```
Set reviewer models and thinking/effort explicitly:
Codex maps thinking to `model_reasoning_effort` and accepts `low`, `medium`,
`high`, or `xhigh`. Claude maps thinking to `--effort` and also accepts `max`.
Engines without a real thinking knob reject `--thinking`.
## Context Efficiency
Codex review is usually noisy. Default to a subagent filter when subagents are available. Ask it to run the review and return only:
- actionable findings it accepts
- findings it rejects, with one-line reason
- exact files/tests to rerun
Run inline only for tiny changes or when subagents are unavailable.
Run the helper directly so target selection, engine choice, structured validation, and exit statusall stay in one path. If output is noisy, summarize the completed helper output after it returns; do not ask another agent or reviewer to rerun the review.
- otherwise uses current PR base if `gh pr view` works
- otherwise uses `origin/main` for non-main branches
- supports `--engine codex`, `claude`, `droid`, and `copilot`; default is `AUTOREVIEW_ENGINE` or `codex`; Codex should remain the default when nothing is set
- use `--mode commit --commit <ref>` for already-committed work, especially clean `main` after landing
- should be left in `--mode auto` or forced to `--mode branch` for PR/branch work; do not force `--mode local` after committing
-supports `--reviewer codex|claude|pi|opencode|auto`; `auto` runs Codex first
- supports `--fallback-reviewer claude|pi|opencode|none`; default is `claude`
-falls back only when Codex is unavailable or exits nonzero, not when Codex reports findings
-writes only to stdout unless `--output` or `AUTOREVIEW_OUTPUT` is set
- supports `--dry-run`, `--parallel-tests`, and commit refs
- runs nested review with `--dangerously-bypass-approvals-and-sandbox` by default
- keeps accepting `--full-access`; use `--no-yolo` or `AUTOREVIEW_YOLO=0` to opt out
- still accepts legacy `CODEX_REVIEW_*` env vars when the matching `AUTOREVIEW_*` var is unset
-writes only to stdout unless `--output` or `--json-output` is set
-supports opt-in review panels with `--panel` / `--reviewers`, plus per-engine `--model` and `--thinking`
-allows read-only tools and web search by default where the selected CLI supports them; forbids nested review in the prompt; Codex is run through `codex exec` with read-only sandbox and structured output
- prints `autoreview clean: no accepted/actionable findings reported` when the selected review command exits 0
- exits nonzero when accepted/actionable findings are present
## Final Report
Include:
- review command used
- tests/proof run
- findings accepted/rejected, briefly why
- the clean review result from the final helper/review run, or why a remaining finding was consciously rejected
Do not run another Codex review solely to improve the final report wording. If the final helper run exited 0 and produced no accepted/actionable findings, report that exact run as clean.
Do not run another review solely to improve the final report wording. If the final helper run exited 0 and produced no accepted/actionable findings, report that exact run as clean.
--prompt "This is an acceptance test fixture. The changed app.js patch contains real security bugs. Review normally and report only actionable defects from the patch." \
--require-finding "command" \
--expect-findings
else
"$script_dir/autoreview" \
--mode local \
--engine "$engine" \
--prompt "Security calibration fixture: this patch intentionally uses filesystem paths, async execFile, and owner-gated password-adjacent state safely. Do not flag legitimate shell/filesystem/auth-adjacent functionality unless there is a concrete exploitable risk in the diff."
description: "Use when previewing local channel message flow fixtures."
---
# Channel Message Flows
Use this from the OpenClaw repo root to send canned channel preview flows while iterating on message UX. These are real sends/edits/deletes against the configured channel target.
## Telegram
Native Telegram `sendMessageDraft` tool progress, then a final answer:
description: Use when testing, fixing, or extending the OpenClaw Control UI GUI with Vitest + Playwright end-to-end checks, mocked Gateway WebSocket flows, mocked dashboard runs, screenshots/videos, or agent-verifiable browser proof.
---
# Control UI E2E
Use this for Control UI changes that need a real browser flow with deterministic Gateway data.
## Test Shape
- Use `ui/src/**/*.e2e.test.ts` for full GUI flows.
- Use `ui/src/test-helpers/control-ui-e2e.ts` to start the Vite Control UI and install a mocked Gateway WebSocket.
- Keep scenarios deterministic. Do not use live provider keys, real channel credentials, or a real Gateway unless the user explicitly asks for live proof.
- Prefer existing `.browser.test.ts` or unit tests for narrow rendering logic; use this E2E lane when the proof should cover routing, app boot, Gateway handshake, requests, and visible UI behavior together.
## Commands
- Target one E2E test in a Codex worktree:
```bash
node scripts/run-vitest.mjs run --config test/vitest/vitest.ui-e2e.config.ts --configLoader runner ui/src/ui/e2e/chat-flow.e2e.test.ts
```
- Run the whole local lane in a normal checkout:
```bash
pnpm test:ui:e2e
```
If dependencies are missing in a Codex worktree, install once with `pnpm install`; for broad GUI proof or dependency-heavy checks, use Testbox/Crabbox instead of running a wide local pnpm lane.
## Visual Proof Default
When running mocked Control UI/dashboard validation for a user-facing feature, produce visual proof by default unless the user explicitly opts out.
- Keep the Vitest E2E assertions deterministic; do not commit generated screenshots or videos.
- After or alongside the focused E2E test, run the mocked Control UI app when available, for example `pnpm dev:ui:mock -- --port <port>`.
- Drive Chromium with Playwright against the local mock URL and capture a video plus screenshots for each meaningful state: initial view, interaction input, result state, and final/paginated/selected state.
- Use `browser.newContext({ recordVideo: { dir, size }, viewport })`, `page.screenshot({ path })`, and close the context before reporting the video path.
- Put artifacts under `.artifacts/control-ui-e2e/<short-feature-name>/` or another clearly named local temp directory, and report the absolute paths in the final answer.
- Treat recording as validation, not only demo capture. If the recorder fails or shows surprising behavior, stop, fix the behavior, add or update a regression test, then rerecord.
- If visual proof is blocked, state the exact blocker and still report the textual E2E evidence.
## Mock Pattern
Start the app server, install the mock before `page.goto`, then assert both Gateway traffic and visible UI:
Extend `installMockGateway` with typed scenario options or method responses when a new flow needs more Gateway surface.
## Standalone Recording
When recording an already-running mocked Control UI URL, use a temporary Playwright script or `playwright test` spec and keep the recording flow focused:
- Open the mock URL, interact through stable `data-*` selectors or user-facing role selectors, and wait on asserted states instead of relying on fixed sleeps.
- Assert both visible UI state and mocked Gateway traffic for request-driven flows. For example, verify the expected count/row is visible and that `sessions.list` was called with the expected `search`, `offset`, and `limit`.
- Use short sleeps only after assertions to make the captured video readable.
- Store the generated video under `.artifacts/control-ui-e2e/<feature>/`; do not commit it.
description: "Find or repair small high-confidence non-SDK-boundary OpenClaw bugfix PRs until five are landable."
---
# OpenClaw Landable Bug Sweep
Autonomous maintainer workflow for producing five landable OpenClaw bugfix PR URLs.
Use for broad issue/PR sweeps where the bar is high and the output is PRs, not notes.
Do not use for plugin SDK/API boundary work; those need separate architecture review.
## Target
Return exactly five PR URLs, each with:
- bug summary
- why the fix is low-risk
- proof: rebased-head local/Testbox/live commands or run IDs
- autoreview: clean result on the exact head being shown
- CI green on the exact pushed PR head
- issue/duplicate cleanup done or still pending
The five URLs may be existing PRs that were reviewed/fixed, or new PRs created from issues/clusters.
Do not present a PR URL to the maintainer until it has been refreshed on current `main`, left-tested, autoreviewed clean, pushed, and verified green in live GitHub CI.
If code, tests, changelog, PR body, or branch base changes after autoreview, rerun autoreview before showing the URL.
## Companion Skills
Use `$gitcrawl` for discovery/clustering, `$openclaw-pr-maintainer` for live GitHub mutation rules, `$github-author-context` when contributor trust matters, `$openclaw-testing` for proof choice, `$autoreview` before publishing/landing, and `$crabbox` for broad/E2E/live proof.
## Candidate Bar
Accept only when all are true:
- bug or paper cut, not feature/product/support/docs-only
- root cause is proven in current code
- dependency behavior checked via upstream docs/source/types when relevant
- production/runtime diff is small, ideally much smaller than 500 LOC and always below 500 LOC
- tests may be larger, but focused
- no new dependency
- no new config option
- no backward-incompatible behavior
- no security/product/owner-boundary decision needed
- no plugin SDK, public plugin API, or `src/plugin-sdk/**` boundary change
- no broad refactor smell
- focused proof is feasible
- branch can be rebased/refreshed and pushed, or a replacement PR can be created
Good examples:
- provider parameter mismatch proven against dependency/API contract
- CLI command diverges from adjacent command behavior
- narrow runtime state/serialization bug with failing test
- issue already fixed on current `main`, with proof and closeable duplicates
Reject:
- feature requests, new knobs, migrations, release work, workflow policy, support
- plugin SDK/API boundary changes, including compatibility shims, new SDK methods, SDK exports, or plugin-facing channel/provider seams
- if already fixed on `main`, prove with current source/test/commit and close kindly
5. Patch:
- prefer existing PR when good and writable
- if unwritable or wrong shape, create own PR and preserve useful contributor credit
- if no PR exists, create one
- add regression test when it fits
- changelog for user-facing fixes; thank credited human reporter/contributor
6. Review, refresh, and publish:
- rebase or otherwise refresh the PR branch on current `origin/main`
- resolve drift, including newly exposed CI failures, rather than counting the PR as ready
- changelog-only conflicts are routine on busy `main`; resolve them mechanically when already refreshing, but do not treat them as a real code conflict, a reason to reject the PR, or evidence that the branch needs extra fixup beyond the changelog entry order
- left-test the rebased head with the smallest meaningful local/Testbox/live command that proves the bug
- run `$autoreview` until no accepted/actionable findings remain before creating, updating, or presenting the PR URL
- create/update PR with real body and proof fields
- push the exact reviewed head
- verify live GitHub CI is green for that pushed head; do not count pending, red, dirty, conflicting, or externally blocked PRs in the five
7. Hygiene:
- close duplicates and fixed-on-main issues/PRs with proof as soon as you notice them during the sweep
- never mutate more than five associated items in one cluster without explicit confirmation
- comments must be kind, concrete, and include proof/PR/commit links
8. Repeat until five landable PR URLs are ready.
## PR Body Proof
Use the repo PR template. Include these exact labels:
```text
Behavior addressed:
Real environment tested:
Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix:
What was not tested:
```
## Existing PR Rules
- Review code path beyond the diff before trusting it.
- If PR is good: rebase/refresh on current `main`, fix small issues, left-test, autoreview clean, push, and get CI green before showing or counting it.
- If PR is not good but has a useful idea: recreate locally, co-author when warranted, close original with thanks and explanation.
- If PR is duplicate or fixed on `main`: comment proof, close.
- If maintainer cannot push to contributor branch: create own branch/PR, preserve useful commits or credit.
- If CI turns red after local proof, treat that as normal work: inspect the failing job, fix or reject, rerun, and only count the PR once green.
short_description:"Find five small non-SDK landable bugfix PRs"
default_prompt:"Use $openclaw-landable-bug-sweep to find or repair five small high-confidence non-SDK-boundary OpenClaw bugfix PRs and get them landable."
description: "Run or recover OpenClaw macOS release signing, notarization, appcast, and asset promotion."
---
# OpenClaw Mac Release
Use with `$openclaw-release-maintainer`, `$openclaw-release-ci`, and `$one-password` when stable macOS assets, private mac preflight, notarization, appcast promotion, or mac release recovery is involved.
## Credentials
- Canonical ASC item: vault `Molty`, title `API Key - App Store Connect - Personal - Release`.
@@ -58,7 +58,7 @@ Use this skill for Parallels guest workflows and smoke interpretation. Do not lo
- For beta/stable verification, resolve the tag immediately before the run (`npm view openclaw@beta version dist.tarball` or `npm view openclaw@latest ...`). Tags can move while a long VM matrix is already running; restart the matrix when the intended prerelease appears after an earlier registry 404/tag-lag check.
- Use the configured secret workflow to inject only the provider keys needed by OpenAI/Anthropic lanes. Do not print secrets or env dumps; pass provider secrets through the guest exec environment.
- Same-guest update verification should set the default model explicitly to `openai/gpt-5.4` before the agent turn and use a fresh explicit `--session-id` so old session model state does not leak into the check.
- The aggregate npm-update wrapper must resolve the Linux VM with the same Ubuntu fallback policy as `parallels-linux-smoke.sh` before both fresh and update lanes. Treat any Ubuntu guest with major version `>= 24` as acceptable when the exact default VM is missing, preferring the closest version match. On Peter's current host today, missing `Ubuntu 24.04.3 ARM64` should fall back to`Ubuntu 25.10`.
- The aggregate npm-update wrapper must resolve the Linux VM with the same Ubuntu fallback policy as `parallels-linux-smoke.sh` before both fresh and update lanes. Treat any Ubuntu guest with major version `>= 24` as acceptable when the exact default VM is missing, preferring the newest versioned Ubuntu guest with a fresh poweroff snapshot. On Peter's current host today, use`Ubuntu 26.04`.
- On macOS same-guest update checks, restart the gateway after the npm upgrade before `gateway status` / `agent`; launchd can otherwise report a loaded service while the old process has exited and the fresh process is not RPC-ready yet.
- The npm-update aggregate's macOS update leg writes the guest update script as root, then runs it as the desktop user. If `prlctl exec "$MACOS_VM" --current-user ...` cannot authenticate, retry through plain root `prlctl exec` plus `sudo -u <desktop-user> /usr/bin/env HOME=/Users/<desktop-user> USER=<desktop-user> LOGNAME=<desktop-user> PATH=/opt/homebrew/bin:/opt/homebrew/opt/node/bin:/usr/bin:/bin:/usr/sbin:/sbin ...`. That is a Parallels transport fallback; still verify `openclaw --version`, gateway RPC, and an agent turn after the update.
- On Windows same-guest update checks, restart the gateway after the npm upgrade before `gateway status` / `agent`; in-place global npm updates can otherwise leave stale hashed `dist/*` module imports alive in the running service.
@@ -93,8 +93,8 @@ Use this skill for Parallels guest workflows and smoke interpretation. Do not lo
- If that release-to-dev lane fails with `reason=preflight-no-good-commit` and repeated `sh: pnpm: command not found` tails from `preflight build`, treat it as an updater regression first. The fix belongs in the git/dev updater bootstrap path, not in Parallels retry logic.
- Until the public stable train includes that updater bootstrap fix, the macOS release-to-dev lane may seed a temporary guest-local `pnpm` shim immediately before `openclaw update --channel dev`. Keep that workaround scoped to the smoke harness and remove it once the latest stable no longer needs it.
- In Tahoe `prlctl exec --current-user` runs, prefer explicit `node .../openclaw.mjs ...` invocations for the release->dev handoff itself and for post-update verification. The shebanged global `openclaw` wrapper can fail with `env: node: No such file or directory`, and self-updating through the wrapper is a weaker lane than invoking the entrypoint under a fixed `node`.
- Default to the snapshot closest to `macOS 26.3.1 latest`.
- On Peter's Tahoe VM, `fresh-latest-march-2026` can hang in `prlctl snapshot-switch`; if restore times out there, rerun with `--snapshot-hint 'macOS 26.3.1 latest'` before blaming auth or the harness.
- Default to the snapshot closest to `macOS 26.5 latest`.
- On Peter's Tahoe VM, `fresh-latest-march-2026` can hang in `prlctl snapshot-switch`; if restore times out there, rerun with `--snapshot-hint 'macOS 26.5 latest'` before blaming auth or the harness.
-`parallels-macos-smoke.sh` now retries `snapshot-switch` once after force-stopping a stuck running/suspended guest. If Tahoe still times out after that recovery path, then treat it as a real Parallels/host issue and rerun manually.
- The macOS smoke should include a dashboard load phase after gateway health: resolve the tokenized URL with `openclaw dashboard --no-open`, verify the served HTML contains the Control UI title/root shell, then open Safari and require an established localhost TCP connection from Safari to the gateway port.
- For Tahoe `fresh.gateway-status`, prefer non-TTY `prlctl exec --current-user ... openclaw gateway status ...` plus a few short retries. `prlctl enter` can spam TTY control bytes and hang the phase log even when the CLI itself is healthy.
@@ -140,8 +140,8 @@ Use this skill for Parallels guest workflows and smoke interpretation. Do not lo
- Use the snapshot closest to fresh`Ubuntu 24.04.3 ARM64`.
- If that exact VM is missing on the host, any Ubuntu guest with major version `>= 24` is acceptable; prefer the closest versioned Ubuntu guest with a fresh poweroff snapshot. On Peter's host today, that is `Ubuntu 25.10`.
- Use the newest versioned Ubuntu guest with a fresh poweroff snapshot. On Peter's host today, that is`Ubuntu 26.04`.
- If an exact requested Ubuntu VM is missing on the host, any Ubuntu guest with major version `>= 24` is acceptable; prefer the newest versioned Ubuntu guest over older fallback snapshots.
- Use plain `prlctl exec`; `--current-user` is not the right transport on this snapshot.
- Fresh snapshots may be missing `curl`, and `apt-get update` can fail on clock skew. Bootstrap with `apt-get -o Acquire::Check-Date=false update` and install `curl ca-certificates`.
- Fresh `main` tgz smoke still needs the latest-release installer first because the snapshot has no Node or npm before bootstrap.
When a maintainer asks Codex to review, triage, fix, or land a specific OpenClaw issue/PR, check assignment before deep work.
- Identify the requesting maintainer's GitHub login. In this environment, default Peter to `steipete`; if another maintainer is clearly the requester, use that maintainer's bare login.
- Read current assignees with live `gh issue view` / `gh pr view`; `gitcrawl` is not enough for assignment state.
- If unassigned, assign the requester before deep review. This is allowed for specific requested targets; do not auto-assign broad discovery candidates or shortlists.
- If assigned to someone else, say so clearly before analysis and include assignment age:
- fresh: assigned within 6h; treat as actively owned unless user explicitly asks to continue or reassign
- stale: assigned 6h+ ago; treat as ownership hint, not a hard block; continue only with that caveat
- If assigned to requester plus others, mention co-assignees and continue.
- If assignment event time is unavailable, say `assigned, time unknown`; treat as assigned, not stale.
- Never remove or replace assignees unless explicitly asked.
Assignment time proof:
```bash
gh api "repos/openclaw/openclaw/issues/<number>/timeline" --paginate \
Use the newest `assigned` event for each current assignee. Issue timeline events expose `created_at`; GitHub GraphQL `AssignedEvent.createdAt` is also valid when REST pagination is awkward.
Claim command for issues or PRs:
```bash
gh api -X POST "repos/openclaw/openclaw/issues/<number>/assignees" -f 'assignees[]=<login>' >/dev/null
```
## Surface opener identity
- For every reviewed, triaged, closed, or landed issue/PR, show the opener's human name when available, GitHub login, and account age.
@@ -139,7 +169,9 @@ Output only qualifying candidates, with: ref, surface, proof, cause, fix sketch,
- Start every PR review with 1-3 plain sentences explaining what the change does and why it matters. Put this before `Findings`.
- Then list findings first. If none, say `No blocking findings` or `No findings`.
- Always answer: bug/behavior being fixed, PR/issue URL and affected surface, provenance for regressions when traceable, and best-fix verdict.
- For bug/regression fixes, include a compact `Provenance:` line after cause/root-cause when a bounded history pass can identify it. Use `git log -S/-G`, `git blame`, linked PRs/issues, and tests; separate author, committer/merger, and current PR author when they differ.
- For bug/regression fixes, include a compact `Provenance:` line after cause/root-cause when a bounded history pass can identify it. Use `git log -S/-G`, `git blame`, linked PRs/issues, and tests.
- Provenance must separate roles when they differ: blamed code author username, blamed PR merger/committer username, current PR author username, PR number, and date. Do not collapse them into one "introduced by" actor.
- For any confirmed bug, run `git blame` on the implicated line(s) after identifying the root cause. Report who broke it as the blamed PR merger/committer, and also name the blamed code author. Include the PR number. If no PR is traceable, use the blamed commit as the provenance: commit SHA, date, and author username. Do not guess a merger or frame missing PR metadata as a separate finding.
- Phrase provenance as `introduced by`, `made visible by`, or `carried forward by`, with confidence (`clear`, `likely`, `unknown`). If unclear, say what evidence is missing instead of guessing. For features, docs, and refactors, use `Provenance: N/A` or omit it when no broken behavior is being fixed.
- Keep summaries compact, but include enough proof that the verdict is auditable without rereading the PR.
@@ -162,7 +194,7 @@ Output only qualifying candidates, with: ref, surface, proof, cause, fix sketch,
- Before landing, require:
1. symptom evidence such as a repro, logs, or a failing test
2. a verified root cause in code with file/line
3. provenance for regressions when traceable by bounded git/PR history
3. blame-backed provenance for regressions when traceable, including blamed PR merger and date, or commit SHA/date when no PR is traceable
4. a fix that touches the implicated code path
5. a regression test when feasible, or explicit manual verification plus a reason no test was added
- If the claim is unsubstantiated or likely wrong, request evidence or changes instead of merging.
- If bot review conversations exist on your PR, address them and resolve them yourself once fixed.
- Leave a review conversation unresolved only when reviewer or maintainer judgment is still needed.
- Before landing any PR with non-trivial code changes, run `$autoreview` until no accepted/actionable findings remain, unless equivalent manual review already covered it, the change is trivial/docs-only, or the user opts out.
- When landing or merging any PR, follow the global `/landpr` process.
- Use `scripts/committer "<msg>" <file...>` for scoped commits instead of manual `git add` and `git commit`.
- Keep commit messages concise and action-oriented.
If env lacks keys, use `$one-password` to inject or set them, then rerun the script. The script prints only provider status and HTTP class, never tokens.
1Password service-account values are the first source for release provider
preflight. Inject those exact targeted keys first, then run the verifier; use
ambient env only when it was already intentionally injected for this release.
The script prints only provider status and HTTP class, never tokens.
- For cancelled same-branch runs, confirm whether a newer run superseded it.
- Fetch full logs only for failed or relevant jobs.
- Prefer `gh run view <run-id> --json jobs` over PR rollup while debugging; rollup can be stale/noisy.
- For `prompt:snapshots:check` failures, treat Linux Node 24 as CI truth. If macOS passes but CI drifts, reproduce in a Linux Node 24 container or Testbox, commit that generated output, then rerun.
This PR description is the contributor's durable explanation of the change. Write it for human maintainers first; ClawSweeper and Barnacle use the same text to understand intent, proof, risk, and current review state.
Describe the intent and outcome in 2-5 bullets. Avoid restating the diff; reviewers and bots can read the changed files.
If this PR fixes a plugin beta-release blocker, title it `fix(<plugin-id>): beta blocker - <summary>` and link the matching `Beta blocker: <plugin-name> - <summary>` issue labeled `beta-blocker`. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation.
- Problem:
- Why it matters:
- What changed:
- What did NOT change (scope boundary):
</details>
## Change Type (select all)
## Linked context
- [ ] Bug fix
- [ ] Feature
- [ ] Refactor required for the fix
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
Which issue does this close?
## Scope (select all touched areas)
Closes #
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
Which issues, PRs, or discussions are related?
## Linked Issue/PR
Related #
- Closes #
- Related #
- [ ] This PR fixes a bug or regression
Was this requested by a maintainer or owner?
<details>
<summary>Linked context guidance</summary>
Link the issue, PR, discussion, maintainer request, or owner request that explains why this PR should exist. Maintainer context helps reviewers and automation distinguish intended work from drive-by churn.
</details>
## Real behavior proof (required for external PRs)
External contributors must show after-fix evidence from a real OpenClaw setup. Unit tests, mocks, lint, typechecks, snapshots, and CI are supplemental only. Screenshots are encouraged even for CLI, console, text, or log changes; terminal screenshots and copied live output count. Be mindful of private information like IP addresses, API keys, phone numbers, non-public endpoints, or other private details when providing evidence.
- Behavior or issue addressed:
- Real environment tested:
- Exact steps or command run after this patch:
- Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):
- Observed result after fix:
- What was not tested:
- Proof limitations or environment constraints:
- Before evidence (optional but encouraged):
## Root Cause (if applicable)
<details>
<summary>Real behavior proof guidance</summary>
For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write `N/A`. If the cause is unclear, write `Unknown`.
External contributors must show after-fix evidence from a real OpenClaw setup. Unit tests, mocks, lint, typechecks, snapshots, and CI are supplemental only.
- Root cause:
- Missing detection / guardrail:
- Contributing context (if known):
Screenshots are encouraged even for CLI, console, text, or log changes. Terminal screenshots, copied live output, redacted runtime logs, recordings, and linked artifacts count.
## Regression Test Plan (if applicable)
If your environment cannot produce the ideal proof, explain that under `Proof limitations or environment constraints` so reviewers and ClawSweeper can direct the next step properly.
For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write `N/A`.
Be mindful of private information like IP addresses, API keys, phone numbers, non-public endpoints, or other private details when providing evidence.
- Coverage level that should have caught this:
- [ ] Unit test
- [ ] Seam / integration test
- [ ] End-to-end test
- [ ] Existing coverage already sufficient
- Target test or file:
- Scenario the test should lock in:
- Why this is the smallest reliable guardrail:
- Existing test that already covers this (if any):
- If no new test is added, why not:
</details>
## User-visible / Behavior Changes
## Tests and validation
List user-visible changes (including defaults/config).
If none, write `None`.
Which commands did you run?
## Diagram (if applicable)
For UI changes or non-trivial logic flows, include a small ASCII diagram reviewers can scan quickly. Otherwise write `N/A`.
List focused commands, not every incidental check. CI is useful support, but external PRs still need real behavior proof above when behavior changes.
- OS:
- Runtime/container:
- Model/provider:
- Integration/channel (if any):
- Relevant config (redacted):
</details>
### Steps
## Risk checklist
1.
2.
3.
Did user-visible behavior change? (`Yes/No`)
### Expected
-
Did config, environment, or migration behavior change? (`Yes/No`)
### Actual
-
Did security, auth, secrets, network, or tool execution behavior change? (`Yes/No`)
## Evidence
Attach at least one:
What is the highest-risk area?
- [ ] Failing test/log before + passing after
- [ ] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
How is that risk mitigated?
What you personally verified (not just CI), and how:
<details>
<summary>Risk guidance</summary>
- Verified scenarios:
- Edge cases checked:
- What you did **not** verify:
Use this for author judgment that is not obvious from the diff. ClawSweeper can see touched files, but it cannot know which behavior you think is risky, why the risk is acceptable, or what mitigation reviewers should verify.
## Review Conversations
</details>
- [ ] I replied to or resolved every bot review conversation I addressed in this PR.
- [ ] I left unresolved only the conversations that still need reviewer or maintainer judgment.
## Current review state
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
What is the next action?
## Compatibility / Migration
- Backward compatible? (`Yes/No`)
- Config/env changes? (`Yes/No`)
- Migration needed? (`Yes/No`)
- If yes, exact upgrade steps:
What is still waiting on author, maintainer, CI, or external proof?
## Risks and Mitigations
List only real risks for this PR. Add/remove entries as needed. If none, write `None`.
Which bot or reviewer comments were addressed?
- Risk:
- Mitigation:
<details>
<summary>Review state guidance</summary>
Keep this as the durable state for review progress. If useful information appears in comments, fold the current next action or blocker back here so maintainers and ClawSweeper do not need to reconstruct state from comment history.
for key in CI GITHUB_ACTIONS GITHUB_WORKSPACE GITHUB_REPOSITORY GITHUB_RUN_ID GITHUB_RUN_NUMBER GITHUB_RUN_ATTEMPT GITHUB_REF GITHUB_REF_NAME GITHUB_SHA GITHUB_EVENT_NAME GITHUB_ACTOR RUNNER_OS RUNNER_ARCH RUNNER_TEMP RUNNER_TOOL_CACHE; do
for key in CI GITHUB_ACTIONS GITHUB_WORKSPACE GITHUB_REPOSITORY GITHUB_RUN_ID GITHUB_RUN_NUMBER GITHUB_RUN_ATTEMPT GITHUB_REF GITHUB_REF_NAME GITHUB_SHA GITHUB_EVENT_NAME GITHUB_ACTOR RUNNER_OS RUNNER_ARCH RUNNER_TEMP RUNNER_TOOL_CACHE XDG_CACHE_HOME COREPACK_HOME PNPM_HOME PNPM_CONFIG_CHILD_CONCURRENCY PNPM_CONFIG_MODULES_DIR PNPM_CONFIG_NETWORK_CONCURRENCY PNPM_CONFIG_STORE_DIR PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN PNPM_CONFIG_VIRTUAL_STORE_DIR; do
write_export "$key"
done
} > "${env_file}.tmp"
mv "${env_file}.tmp" "$env_file"
{
echo "# Docker containers visible from the hydrated runner"
--arg notes "Automatically requested by Full Release Validation ${GITHUB_RUN_ID_VALUE} after child workflows completed; the parent summary re-checks current child run conclusions." \
evidence_summary="Mantis ran Slack QA inside a Crabbox Linux VNC desktop, started an OpenClaw Slack gateway in that VM, opened Slack Web in the visible browser, and captured screenshot/video evidence."
expected_result="Slack QA and VM gateway setup pass"
checkpoint_artifacts='[]'
checkpoint_required=false
if [[ "$APPROVAL_CHECKPOINTS" == "true" ]]; then
evidence_summary="Mantis ran Slack native approval QA inside a Crabbox Linux VNC desktop, rendered pending/resolved approval checkpoints from the Slack API messages, and stored Slack QA artifacts."
expected_result="Slack native exec and plugin approval checkpoints pass"
screenshot_required=false
desktop_capture_inline=false
if [[ "$status" == "pass" ]]; then
checkpoint_required=true
fi
checkpoint_scenarios=()
if [[ "$scenario_label" == "approval-checkpoints" ]]; then
summary: "Mantis ran Slack QA inside a Crabbox Linux VNC desktop, started an OpenClaw Slack gateway in that VM, opened Slack Web in the visible browser, and captured screenshot/video evidence.",
summary: $summary,
scenario: $scenario,
comparison: {
candidate: { sha: $candidate_sha, expected: "Slack QA and VM gateway setup pass", status: $status, fixed: ($status == "pass") },
clawhub_line="- plugin ClawHub publish: dispatched separately, not awaited by this proof: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${plugin_clawhub_run_id}"
if approve_child_publish_environment plugin-clawhub-release.yml "${plugin_clawhub_run_id}"; then
:
else
echo "- plugin-clawhub-release.yml: child environment gate not ready; publish was left dispatched (${plugin_clawhub_run_id})" >> "$GITHUB_STEP_SUMMARY"
fi
echo "- plugin-clawhub-release.yml: publish not awaited (${plugin_clawhub_run_id})" >> "$GITHUB_STEP_SUMMARY"
fi
openclaw_result=""
@@ -760,6 +933,7 @@ jobs:
if [[ "${failed}" == "0" && -n "${openclaw_npm_run_id}" ]]; then
- ClawSweeper-owned schema, labels, close reasons, protected-label gates, maintainer-item gates, and mutation rules live in `openclaw/clawsweeper`.
- Review workers read this full root `AGENTS.md` before judging; no reliance on search snippets, `head`, partial ranges, local excerpts, or truncated copies. Then read every scoped `AGENTS.md` that owns touched paths.
- Optional integrations, providers, channels, skill bundles, MCP surfaces, and service workflows route to plugins, ClawHub, or owner repos when current seams suffice. Keep core items for missing core/plugin APIs, bundled regressions, security/core hardening, or maintainer product decisions.
- Plugin APIs, provider routing, auth/session state, persisted preferences, config loading, migrations, setup, startup checks, and fallback behavior are compatibility/upgrade-sensitive. Treat config breaks, removed fallbacks, fail-closed changes, or new operator action as merge risk even with green CI.
- Review whole decision surfaces, not only the touched runtime, provider, channel, harness, plugin seam, or context path. Check sibling Codex/Pi-style runtimes, provider/model routing, channel delivery, gateway/protocol, plugin SDK, and context-management paths when relevant.
- One-sided fixes need sibling-surface proof, an explanation for why siblings are unaffected, or explicit follow-up work.
- User-facing `fix`, `feat`, and `perf` changes need `CHANGELOG.md` before landing; contributor PR authors are not blocked solely on maintainer-owned changelog work. Never request thanks for bot/forbidden handles: `@openclaw`, `@clawsweeper`, `@codex`, `@steipete`.
- Public ClawSweeper comments prefer `https://docs.openclaw.ai/...` when a public docs page exists; structured evidence still cites repo files, lines, SHAs.
- Findings need current source, shipped/current behavior, tests/CI evidence, and dependency contract proof when dependency-backed behavior is involved. Validation is judged against touched and sibling surfaces plus this file's commands; real behavior proof matters for user-visible changes, with Telegram/Desktop proof for Telegram-visible behavior when feasible.
- Prefer findings for concrete behavior regressions, missing changed-surface proof, owner-boundary violations, security/API contract issues, or docs/config mismatches.
- Do not file findings for repo policy preference when changed code follows the relevant scoped guide and no user-visible, runtime, security, or maintainer-risk impact is shown.
- Docs AI: `openclaw/ask-molty`; see its `AGENTS.md`.
## Architecture
- Core stays plugin-agnostic. No bundled ids/defaults/policy in core when manifest/registry/capability contracts work.
@@ -35,12 +56,17 @@ Skills own workflows; root owns hard policy and routing.
- External official plugins own package/deps and are excluded from core dist; core uses registry-aware `facade-runtime` or generic contracts.
- Externalizing a bundled plugin: update package excludes, official catalogs, docs, tests, and prove core runtime paths resolve installed plugin roots before root-dep removal.
- Legacy config repair belongs in `openclaw doctor --fix`, not startup/load-time core migrations. Runtime paths use canonical contracts.
- Fix shape: prefer bounded owner-boundary refactors over local patches/shims when they remove stale abstractions, duplicate policy, or wrong ownership.
-Compat default: no new internal shims, aliases, fallback APIs, or legacy names just to reduce diff. Migrate callers and delete old paths.
-Public plugin API is the only compat exception: document/version breaks, aggressively deprecate unused SDK surface, and migrate ALL bundled/internal plugins to the modern API in the same change.
- Fix shape: default to clean bounded refactor, not smallest patch. Move ownership to right boundary; delete stale abstractions, duplicate policy, dead branches, wrappers, fallback stacks.
-Lean code is a goal. No internal shims, aliases, legacy names, broad fallbacks, or defensive branches just to reduce diff or handle unrealistic edge cases.
-Handle real production states, shipped upgrade paths, security boundaries, and dependency contracts. Public/hostile/observed malformedinput gets care; hypothetical malformed input does not.
- Public plugin SDK/API is the compat exception. New API first, old path only via named compat/deprecation metadata, docs, warnings when useful, tests for old+new, planned removal.
- Migrate internal/bundled callers to modern API in the same change. Do not let internal compat become permanent architecture.
- Channels are implementation under `src/channels/**`; plugin authors get SDK seams. Providers own auth/catalog/runtime hooks; core owns generic loop.
- Hot paths should carry prepared facts forward: provider id, model ref, channel id, target, capability family, attachment class. Do not rediscover with broad plugin/provider/channel/capability loaders.
- Do not fix repeated request-time discovery with scattered caches. Move the canonical fact earlier; reuse prepared runtime objects; delete duplicate lookup branches.
- Gateway/plugin metadata is process-stable: installs, manifests, catalogs, generated paths, bundled metadata. Changes require restart or explicit owner reload/install/doctor flow.
- Runtime hot paths: no freshness polling (`stat`/`realpath`/JSON reread/hash). Reuse current snapshots, install records, discovery, lookup tables, root scopes, resolved paths.
- Process-local metadata caches ok when lifecycle-owned and bounded/single-slot. Freshness exceptions need named owner + tests.
- Inline code comments: brief notes for tricky, bug-prone, or previously buggy logic.
@@ -77,10 +103,12 @@ Skills own workflows; root owns hard policy and routing.
- If proof is blocked, say exactly what is missing and why.
- Do not land related failing format/lint/type/build/tests. If unrelated on latest `origin/main`, say so with scoped proof.
- Docs/changelog-only and CI/workflow metadata-only: `git diff --check` plus relevant docs/workflow sanity; escalate only if scripts/config/generated/package/runtime behavior changed.
- Prompt snapshots: CI truth is Linux Node 24. If macOS local passes but CI drifts, reproduce/generate in Linux before rerun.
## GitHub / PRs
- Use `$openclaw-pr-maintainer` immediately for maintainer-side OpenClaw issue/PR review, triage, duplicates, labels, comments, close, land, or evidence. Contributor PR creation/refresh follows the requested contributor workflow; linked refs alone do not require maintainer archive tooling.
- Pasted GitHub issue/PR: first `git status -sb`; if dirty, yell; then `git push` + `git pull --ff-only`.
- PR refs: `gh pr view/diff` or `gh api`, not web search. Prefer `gitcrawl` for maintainer discovery; missing/stale `gitcrawl` falls through to live `gh`, not contributor setup. Verify live with `gh` before mutation.
- Bare issue/PR URL/number means review/report in chat. Suggest comment/close/merge when appropriate; mutate only when asked.
- No unsolicited PR comments/reviews/labels/retitles/rebases/fixups/landing. Exception: close/duplicate action that needs a reason comment after explicit close/sweep/landing request.
@@ -108,6 +136,10 @@ Skills own workflows; root owns hard policy and routing.
- No `@ts-nocheck`. Lint suppressions only intentional + explained.
- External boundaries: prefer `zod` or existing schema helpers.
- Formatter-friendly shape: when oxfmt explodes an expression vertically, extract named booleans, payloads, or small helpers. Do not change width or use format-ignore for local compactness.
- Calls should be boring: complex decisions happen above; call args/object fields are names, literals, or simple property reads.
- Prefer early returns over nested condition pyramids. Split code into gather -> normalize -> decide -> act.
- Use named intermediates only for domain meaning or readability; avoid temp-variable soup.
- Dynamic import: no static+dynamic import for same prod module. Use `*.runtime.ts` lazy boundary. After edits: `pnpm build`; check `[INEFFECTIVE_DYNAMIC_IMPORT]`.
@@ -164,6 +197,7 @@ Skills own workflows; root owns hard policy and routing.
- "restart iOS/Android apps" = rebuild/reinstall/relaunch, not kill/launch.
- SwiftUI: Observation (`@Observable`, `@Bindable`) over new `ObservableObject`.
- Mac gateway: dev watch = `pnpm gateway:watch`; managed installs = `openclaw gateway restart/status --deep`; logs = `./scripts/clawlog.sh`. No launchd/ad-hoc tmux.
- Mac app permission testing: stable app path + real signing identity required. No `--no-sign`, `SIGN_IDENTITY=-`, or raw debug binary; TCC prompts/listing won't stick.
- Version bump surfaces live in `$openclaw-release-maintainer`.
- Scripts: remove stale Knip unused-file allowlist entries so the dead-code gate fails only on current findings.
- Tests: normalize bundled plugin lifecycle probe paths and state-root lookup so native Windows release sweeps accept valid packaged plugin installs.
- Config: keep benign legacy metadata write anomalies out of default doctor and config command output while preserving explicit anomaly logging for diagnostics.
- Agents/Codex: route budget preflight compaction through the persisted Codex session model so Slack threads do not require separate plain OpenAI auth. Thanks @amknight.
- Codex: log when implicit app-server `never` approvals are promoted for OpenClaw tool policy, including whether the trigger was a `before_tool_call` hook or trusted tool policy.
- Google Vertex: support production ADC modes such as Workload Identity Federation, service-account credentials, and metadata-server ADC for the native Vertex transport. (#83971) Thanks @damianFelixPago.
- Telegram: route normal `[telegram][diag]` polling diagnostics through `runtime.log` while keeping non-diag warnings and persistence failures on `runtime.error`, so healthy polling startup no longer looks like an error. Fixes #82957. (#82958) Thanks @galiniliev.
## 2026.5.25
### Fixes
- Installer: let the local-prefix CLI installer use Alpine's `apk` Node.js, npm, and Git packages on musl Linux instead of downloading glibc Node tarballs that fail `node:sqlite`.
- Scripts: use `git grep` to prefilter tracked conflict-marker scans so changed checks avoid reading every repository file on clean runs.
- Plugins: allow linked local plugin paths to probe TypeScript source entries without requiring compiled package output, restoring source-checkout plugin development on native Windows.
- CLI: route source-checkout build output to stderr before launching OpenClaw commands so stale local builds do not corrupt `--json` stdout.
- Installer: install Node.js through `apk` on Alpine Linux instead of falling through to the NodeSource package-manager path.
- Agents/perf: cache manifest-backed CLI provider descriptors and fallback provider resolution so model fallback retries avoid repeated bundled provider runtime scans while still invalidating across plugin reloads.
- Installer: detect musl Linux shells such as Alpine as Linux instead of rejecting them before npm install.
- Scripts: run direct Node package scripts with env overrides through a cross-platform launcher so gateway, TUI, and Docker-all entrypoints work on native Windows.
- Tests: run Vitest import timing entrypoints through a Node wrapper so native Windows package scripts can collect import diagnostics.
- Control UI: split large build-time runtime dependencies into stable chunks so Linux/Docker install and package builds stay below the app chunk warning threshold.
- Tests: run `test:max` and `test:changed:max` through a Node wrapper so high-worker Vitest entrypoints work on native Windows.
- Tests: retry transient loopback HTTP resets in the kitchen-sink RPC walk so native Windows readiness probes do not fail after the gateway is already ready.
- Tests: run `test:serial` through a Node wrapper so targeted serial Vitest commands work on native Windows.
- Tests: normalize Vitest config path assertions so the infra config suite runs on native Windows paths.
- Scripts: run the optional Discord native opus installer through the shared pnpm launcher and Windows CI coverage so native Windows installs avoid shell-mode package-manager shims.
- Installer: avoid the incompatible generated `--before` install filter when raw npm `min-release-age` config is present. (#85491) Thanks @TurboTheTurtle.
- Agents/MCP: bound bundled MCP `tools/list` catalog discovery so hung MCP servers do not block session tool materialization. (#85063) Thanks @nxmxbbd.
- Scripts: run generated-module formatting through the shared pnpm launcher and Windows CI coverage so native Windows generator checks avoid shell-mode package-manager shims.
- Channels/iMessage: recover malformed anchorless group watch payloads by GUID before debounce/routing, and drop unrecoverable payloads instead of replying to the sender DM. Fixes #84470. Refs #84503. Thanks @zhangguiping-xydt and @zqchris.
- Channels/iMessage: advance the startup catchup cursor from live-handled rows after a completed catchup pass, including rows received while catchup is still running, so restarts do not replay them. (#85475) Thanks @TurboTheTurtle.
- Tests: mount the shared Windows command helper into bare Docker E2E harness containers so published upgrade-survivor config walks can start on Linux.
- Tests: keep the plugin binding command escape Docker smoke focused on its intended Vitest cases and skip source-only install lifecycle scripts.
- Tests: let the generic plugin install E2E assertions use a configurable temp root and Windows home-relative install paths.
- Tests: keep kitchen-sink plugin assertion fixtures on a configurable temp root so native Windows runs no longer skip full-surface diagnostic coverage.
- Tests: fail Gateway startup benchmarks when a child startup never produces ready probes or process metrics instead of reporting all `n/a` samples as passing.
- Config/secrets: allow exec SecretRef ids to include `#` selectors so AWS-style `secret#json_key` ids validate consistently. (#80731) Thanks @TurboTheTurtle.
- Tests: keep the Telegram user credential helper on platform temp and path APIs so native Windows credential export and restore commands do not write through POSIX-only paths.
- Installer: include the optional verify phase in the progress counter so `--verify` shows `[4/4] Verifying installation` instead of `[4/3]`.
- Crabbox: let the wrapper find a sibling Crabbox checkout from linked Git worktrees so Codex worktrees can run remote gates without a PATH shim.
- Scripts: tolerate the standard `--` option separator in shared script flag parsing so perf/test helpers accept package-manager argument forwarding.
- Tests: preserve `--` passthrough arguments in live-media, live-shard, and extension batch harnesses so Vitest filters are not misread or silently ignored.
- Crabbox: default AWS macOS runner requests to on-demand capacity so EC2 Mac proof commands do not fail on the unsupported Spot market default.
- Tests: run upgrade-survivor config recipe commands through the Windows npm shim so native Windows package walks keep baseline config coverage.
- Image tool: use bundled Anthropic media limits when resolving image compression policy without provider-runtime hooks.
- Tests: fail the kitchen-sink RPC Docker walk when gateway RSS sampling is unavailable instead of silently disabling the per-process memory guard.
- Tests: suppress the current Rolldown plugin timing warning format in the Vitest wrapper so tiny focused runs do not drown useful stderr in repeated build-timing noise.
- Models/OpenRouter: use endpoint-specific OpenRouter context limits from `top_provider` metadata so provider-routed models no longer overstate available context. (#85949) Thanks @TurboTheTurtle.
- Crabbox: sync clean sparse-checkout remote changed gates from a temporary full checkout with local-only commits overlaid as worktree changes so git-backed script checks can seed the runner repository.
- Agents: avoid loading bundled channel plugins while resolving completion delivery policy and queue defaults on subagent handoff paths.
- Tests: allow split Vitest config shards through the explicit-target preflight so CI shard jobs run their intended projects.
- Tests: make startup memory and startup bench smoke scripts build CLI startup artifacts when run from a fresh source checkout.
- iMessage: mark authorized slash-command turns as text-sourced commands so `/status`, `/new`, and `/restart` acknowledgements return to the source conversation. (#82642) thanks @homer-byte.
- Crabbox: install Corepack shims into the writable hydration `PNPM_HOME` so local AWS runner hydration no longer tries to overwrite `/usr/local/bin/pnpm`.
- Live tests: fail Gateway live model sweeps when selected coverage is lost to timeouts or stale high-signal filters instead of reporting false missing-profile coverage, and pin Docker OpenAI gateway coverage to the current `gpt-5.5` lane.
- Tests: fail Docker resource-ceiling checks when stats samples or configured limits are invalid instead of silently reporting zero peaks.
- Agents: fail closed when provider-less session models match multiple provider-prefixed runtime policies so CLI runtime routing no longer depends on config order. (#85970) Thanks @potterdigital.
## 2026.5.24
### Changes
- iMessage: support thumb-approval reactions — `👍` (Like tapback) resolves an approval as `allow-once` and `👎` resolves as `deny`, with the explicit-approver allowlist read from `channels.imessage.allowFrom`; `allow-always` stays on the manual `/approve <id> allow-always` text fallback. Mirrors the WhatsApp behavior from #85477.
- Gateway/perf: reuse process-stable channel catalog reads, avoid repeated bundled-channel boundary checks, and rotate gateway watch CPU profiles so benchmark runs do not accumulate unbounded artifacts.
- Gateway/perf: cache stable install-record, channel-catalog, bundled-channel, and Telegram session-store metadata during process-local hot paths to reduce repeated JSON and manifest reads.
- Gateway/perf: reuse immutable plugin metadata snapshots across startup, config, model, channel, setup, and secret metadata readers so hot paths avoid repeated plugin file stats and manifest registry reloads.
- Talk/realtime: let WebUI and Discord voice callers ask for active OpenClaw run status, cancel, steer, or queue follow-up work while a consult is still running. (#84231) Thanks @Solvely-Colin.
- Discord/voice: add realtime wake-name gating with agent-name defaults and raise profile bootstrap context budget for longer `USER.md`/`SOUL.md` files.
- Gateway/perf: lazy-load startup-idle plugin work, core gateway method handlers, and the embedded ACPX runtime so Gateway health and ready signals no longer wait on unused handler trees or ACPX probes.
- Gateway/perf: cache plugin SDK public-surface alias maps and skip irrelevant macOS Linuxbrew PATH probes so Gateway startup avoids repeated filesystem walks and slow missing-directory stats.
- Image tool: add adaptive model-aware image compression with an `agents.defaults.imageQuality` preference for choosing token-efficient, balanced, or high-detail media handling.
- Meeting Notes: add a source-only external meeting-notes plugin and SDK source-provider contract outside the core npm package, with auto-start capture config, manual transcript imports, read-only `openclaw meeting-notes` CLI access, and Discord voice as the first live source.
- Meeting Notes/Discord: release channel account startup before meeting-notes auto-capture, wait for the Discord voice manager during gateway boot, and stop plugin services before channel shutdown so voice capture state remains available during startup and cleanup.
- Docs/channels/config: add Signal `configPath`, Telegram wildcard topic defaults, local-time backup archive names, Termux home fallback, include-path validation, secret-scanner-safe placeholder guidance, Gemini CLI/Antigravity media guidance, and macOS VM auto-login guidance. Thanks @NorseGaud, @yudistiraashadi, @huangqian8, @VibhorGautam, @maweibin, @tianxingleo, @IgnacioPro, and @xzcxzcyy-claw.
- Docs: clarify model-usage portability, Codex migration prerequisites, status bootstrap wording, thread-bound subagent limits, hook ownership, and config-preserving safety guidance. Thanks @aniruddhaadak80, @leno23, @TomDjerry, @matthewxmurphy, @vincentkoc, and @stablegenius49.
- Docs: clarify README onboarding and Gateway startup paths, WhatsApp QR/408 recovery, cron output language prompts, skill advanced features, gateway upstream 403 troubleshooting, and plugin fallback override guidance. Thanks @deepujain, @Zacxxx, @Jah-yee, @neyric, @usimic, @Renu-Cybe, @BigUncle, and @SeashoreShi.
- Docs: clarify context-pruning ratio bounds, local dashboard recovery, CLI env markers, remote onboarding token behavior, and Peekaboo Bridge permissions for subprocess agents. Thanks @ayesha-aziz123, @dishraters, @hougangdev, and @brandonlipman.
- CLI/models: let `openclaw models auth login` store a single returned provider auth profile under a requested `--profile-id`, and document named Codex OAuth profile setup. (#49315) Thanks @DanielLSM.
- Crabbox/Testbox: run clean sparse-checkout Testbox syncs from a temporary full checkout and route remote changed gates through Corepack pnpm.
- Docs: consolidate GLM under Z.AI, add the Upstash Box install guide and Gateway exposure runbook, clarify MEDIA directives, Copilot and Voyage setup, config path quoting, real behavior proof, and memory-file write guidance. Thanks @BobDu, @alitariksahin, @Jefsky, @musaabhasan, @OmerZeyveli, @leno23, @WuKongAI-CMU, @luoyanglang, and @majin1102.
- Docs: clarify media provider credentials, Codex/OpenClaw code-mode boundaries, Slack and Telegram ack reactions, Feishu dynamic agents, secrets plaintext boundaries, memory guidance, and Chinese glossary terms. Thanks @nielskaspers, @cosmopolitan033, @drclaw-iq, @alexgduarte, @zccyman, @chengoak, and @cassthebandit.
- Packaging: exclude documentation images and assets from the npm tarball, reducing published package size without affecting runtime docs search or CLI behavior. Thanks @SebTardif.
- Media understanding: stop auto-probing Gemini CLI and use Antigravity CLI only as a lower-priority image/video fallback after configured provider APIs.
- Diagnostics: emit sanitized `secrets.prepare` timeline spans for Gateway secret preparation so operators can distinguish secret startup latency without exposing provider names, secret ids, or secret values. (#83019) Thanks @samzong.
- Diagnostics: export bounded skill usage metrics/spans and tool source/owner labels for core, plugin, MCP, and channel tool execution without exposing raw paths or session identifiers. (#80370) Thanks @gauravprasadgp.
- Agents/subagents: limit default sub-agent bootstrap context to `AGENTS.md` and `TOOLS.md`, keeping persona, identity, user, memory, heartbeat, and setup files out of delegated workers by default. (#85283) Thanks @100yenadmin.
- Maintainer skills: require clean autoreview before surfacing bug-sweep PR URLs and treat changelog-only conflicts as routine busy-main churn.
- Maintainer skills: exclude plugin SDK/API boundary work from `openclaw-landable-bug-sweep` so bugbash sweeps stay focused on small paper-cut fixes.
- QA-Lab/diagnostics: extend the OpenTelemetry smoke harness to prove trace, metric, and log export, and add first-class Prometheus and observability smoke aliases.
- Plugin SDK: add a generic channel-message poll sender so channel plugins can expose poll delivery without depending on channel-specific SDK facades.
- Plugin SDK/cron delivery: route cron delivery through the modern target resolver and outbound session-route APIs, deprecate parser-backed target helpers and `plugin-sdk/messaging-targets`, and move bundled callers to `plugin-sdk/channel-targets`.
- Crabbox: keep the local wrapper's provider validation synced with the installed Crabbox binary while preserving supported aliases such as `docker` and `blacksmith`. (#85302) Thanks @hxy91819.
- Maintainer skills: add `openclaw-landable-bug-sweep` for producing five small, reviewed, CI-green OpenClaw bugfix PRs from issue/PR sweeps.
- Control UI/chat: add search and Load More pagination to the chat session picker, keeping initial session loads bounded while making older conversations reachable. (#85237) Thanks @amknight.
- CLI/onboarding: start classic onboarding when bare `openclaw` runs before an authored config exists, while keeping configured installs on Crestodian. (#72343) Thanks @fuller-stack-dev.
- Discord: allow configuring a bounded `agentComponents.ttlMs` callback registry lifetime for long-running component workflows, with per-account overrides and a 24-hour cap. (#84189) Thanks @100menotu001.
- xAI/Grok: reuse xAI OAuth auth profiles for Grok `web_search`, thread active-agent auth through web search, add Grok model aliases, and let media providers declare default operation timeouts. (#85182) Thanks @fuller-stack-dev.
- Plugin SDK: add row-level session workflow helpers and deprecate `loadSessionStore` so plugins can read and patch sessions without depending on the legacy whole-store shape. (#84693) Thanks @efpiva.
- Gateway/plugins: reuse a compatible Gateway startup plugin registry during dispatch so safe plugin dispatches avoid redundant registry loading. (#84324) Thanks @ai-hpc.
- Plugins/SDK: add a general `embeddingProviders` capability contract and registration API so embeddings can become a reusable provider surface outside memory-specific adapters.
- Dependencies: refresh provider, plugin, UI, and tooling packages, update `protobufjs` to 8.4.0 to clear the current npm advisory, and carry the Claude ACP completion patch forward to `@agentclientprotocol/claude-agent-acp` 0.36.1.
- Agents/tools: remove the old sender-owner tool gating path so configured tools stay visible for trusted sessions while command and channel-action auth still carry real sender identity.
- QA-Lab: add curated mock JSONL replay fixtures and first-drift reporting for runtime-parity audits. (#80323, refs #80176) Thanks @100yenadmin.
- QA-Lab: add a QA bus tool-trace visibility scenario for sanitized tool-call assertions.
- QA-Lab: replace generic evidence framing in seeded scenario prompts with concrete observed QA behavior.
- QA-Lab: list named scenario packs in the coverage report so personal-agent privacy coverage stays visible in audits.
- QA-Lab: list live transport lane membership in the coverage report so real transport checks stay separate from seeded qa-channel scenarios.
- Release/package: run package integrity checks before package acceptance lanes so public install/update validation fails before private QA assets can leak into the package.
- QA-Lab: include the optional 100-turn runtime parity soak in release-soak artifacts so long-run Codex/Pi transcript drift stays visible outside the default gate. (#80395) Thanks @100yenadmin.
- QA-Lab: add a live-only long-context progress watchdog scenario for Codex app-server timeout and stalled-run sentinels. (#80323) Thanks @100yenadmin.
- QA-Lab: tag gateway restart recovery and streaming final-integrity scenarios as live-only runtime parity lanes. (#80323) Thanks @100yenadmin.
- QA-Lab: add a personal-agent failure recovery scenario that checks honest partial status, retry boundaries, and local recovery artifacts. (#83872) Thanks @iFiras-Max1.
- QA-Lab: include an opt-in `update.run` package self-upgrade sentinel for destructive latest-package recovery checks.
- QA-Lab: add Codex plugin lifecycle and auth-profile fixture coverage for missing installs, pinned-version drift, first-turn install ordering, and doctor migration safety. (#80323, refs #80174) Thanks @100yenadmin.
- Models/perf: pre-warm the provider auth-state map at gateway startup so `/models` and every model-listing call short-circuits the per-provider plugin / external-CLI discovery on the hot path. Per-call cost drops from ~20 s to ~5 ms (~4,100×); the one-time startup warm resets and re-warms after hot reloads. (#84816) Thanks @sjf.
- Release/security: ship the root npm package and OpenClaw-owned npm plugins with generated shrinkwrap, support bundled plugin runtime dependencies for suitable plugin tarballs, and require review for lockfile/shrinkwrap changes so published installs use locked dependency graphs.
- Tests/perf: isolate doctor core health check unit coverage from real skills/workspace discovery so `doctor-core-checks` no longer dominates unit perf while keeping one real skills-readiness smoke. (#84493) Thanks @frankekn.
### Fixes
- Gateway/update: avoid fetching unrelated tags during dev-channel git updates so moved release tags do not block branch-based updates. (#84737) Thanks @rubencu.
- CLI/update: suppress the expected future-config warning while an old update parent hands off to the freshly installed post-core process.
- MiniMax: store OAuth token expiry as an absolute millisecond timestamp so OAuth profiles no longer appear expired on every request. (#83480) Thanks @NianJiuZst.
- Agents/Anthropic: strip missing or blank thinking signatures for signed-thinking providers even when recovery supplies a narrow replay policy without signature preservation. Fixes #84430. (#84448) Thanks @NianJiuZst.
- Agents/channels: send a visible notice when an aborted main session cannot be resumed after restart, including Telegram group targets. (#85805) Thanks @pfrederiksen.
- Discord/voice: serialize overlapping voice joins, retry aborted startup readiness within the configured timeout, upgrade meeting-notes-only sessions to realtime when the normal follow join arrives, detach promoted meeting-notes ownership without leaving voice, and include `OpenClaw` in default realtime wake names.
- Gateway/restart: honor the configured restart drain budget for embedded runs and avoid spending the deferral timeout twice after forced restart timeouts. (#85708) Thanks @Kaspre.
- Gateway/boot: run `BOOT.md` startup checks in an isolated boot session so gateway restarts do not overwrite the agent's main session mapping. (#85479)
- Meeting Notes: include a speaker-labeled transcript section in generated summaries so Discord group voice captures show who said each captured utterance.
- Discord/voice: recover stale realtime playback state when Discord stream-close/player-idle events do not arrive, and keep generated runtime plugin aliases available after postbuild rewrites.
- Discord/voice: keep realtime playback running when meeting notes attaches to an existing voice session or a realtime consult starts, and route realtime user transcripts into meeting notes.
- Config/secrets: preflight active runtime SecretRefs before root and include config writes persist, and roll back unchanged file/env state when post-write refresh fails. Fixes #46531. (#84454) Thanks @samzong.
- WhatsApp/auto-reply: deliver deferred media replies through the foreground reply fence so overlapping no-reply turns no longer hide already visible responses. (#85517) Thanks @cavit99.
- Sessions/security: replace agent-to-agent wildcard allowlist regexes with a precompiled linear matcher so cross-agent access checks avoid backtracking-prone patterns. (#85849) Thanks @SebTardif.
- WebChat: keep the run-complete indicator in progress until deferred history replay renders the assistant reply, so Done no longer appears before response text. (#85374) Thanks @neeravmakwana.
- Agents/tools: give timed-out or cancelled process trees a bounded SIGTERM cleanup window before SIGKILL while preserving tree-aware cancellation. Fixes #66399. (#85865) Thanks @IWhatsskill.
- Agents/subagents: treat aborted subagent stop reasons as killed terminal failures so parent sessions get error announcements instead of silent success. Fixes #72293. (#85860) Thanks @IWhatsskill.
- Agents/providers: clamp proxy-like OpenAI Chat Completions output caps against the final request payload so strict local/API-compatible servers no longer reject prompts that already consume part of the context window. Fixes #83086. (#85889) Thanks @rendrag-git.
- Agents/compaction: skip agent-harness preflight for provider-owned CLI runtime sessions so over-threshold Claude CLI sessions continue through normal compaction instead of failing on a missing harness. Fixes #84857. (#84878) Thanks @zhangguiping-xydt.
- Codex/app-server: keep successful native hook relays available through a short post-turn grace window so late Codex hook subprocesses can finish policy enforcement without clearing a replacement relay. (#83987) Thanks @Kaspre.
- Control UI/config: save form-mode edits from the source config snapshot so runtime-only provider defaults like empty `models.providers.<id>.baseUrl` are not written back and rejected. Fixes #85831. Thanks @garyd9.
- Browser/existing-session: launch Chrome DevTools MCP with usage statistics disabled by default so its telemetry watchdog stays off unless an operator explicitly opts in. (#85886) Thanks @rohitjavvadi.
- Telegram: normalize legacy durable group retry targets before retry sends, polls, and pins so group retries keep using the real chat id. (#85656) Thanks @luoyanglang.
- Agents/PDF: route MiniMax PDF fallback policy through plugin metadata so MiniMax uses text extraction instead of VLM image fallback. (#85590, fixes #85575) Thanks @neeravmakwana.
- CLI/plugins: tighten timeout, numeric option, media payload, permission, profile/TLS, plugin metadata, JSON, and remote URL handling; prevent stuck progress/app-server/IRC/Synology/Twitch waits; and keep imported chat history ordering stable.
- Telegram/config: suppress the missing `accounts.default` warning when `channels.telegram.defaultAccount` names a configured account that also sorts first. Fixes #83948. Thanks @crypto86m.
- Telegram: serialize visible topic replies through core reply-lane admission so heartbeat and queued follow-up turns cannot continue ownerless or misroute responses. (#85709) Thanks @jalehman.
- CLI/node: print node status recovery hints on stdout consistently while keeping status errors on stderr. Fixes #83925. Thanks @davinci282828.
- WebChat: summarize internal message-tool source replies so tool cards no longer duplicate the visible reply body. (#84773) Thanks @jason-allen-oneal.
- Gateway/WebChat: hide duplicate `gateway-injected` assistant rows when Cursor ACP already persisted the same `acp-runtime` reply. Fixes #85741. Thanks @lxf-lxf.
- WebChat: scope the visible attachment button to its own composer file input so clicking Upload reliably opens the file picker. (#83952, fixes #47983) Thanks @jason-allen-oneal.
- Gateway: preserve deferred lifecycle-error cleanup across later non-terminal events so provider timeouts can persist failed session state instead of leaving sessions stuck running. (#85256, fixes #63819) Thanks @samzong.
- Gateway/update: stop treating inherited macOS `XPC_SERVICE_NAME` values as launchd supervision during update respawn, so GUI-spawned gateways use detached respawn instead of exiting for a missing LaunchAgent. Fixes #85224. Thanks @richardmqq.
- Agents/subagents: report tool-only child progress during timeout summaries instead of showing no visible output.
- Telegram/ACP: preserve explicit `:topic:` conversation suffixes when inbound ACP targets do not carry a separate thread id.
- Browser/proxy: bypass the managed proxy for the exact local managed Chrome CDP readiness and DevTools WebSocket endpoints, so `openclaw browser start` works when the operator proxy blocks loopback egress. (#83255) Thanks @lightcap.
- Ollama: bypass the managed proxy for configured local embedding origins while keeping SSRF guardrails on unconfigured targets. Thanks @Kaspre.
- OpenAI/images: route Codex API-key image generation through the native OpenAI Images API instead of the Codex OAuth streaming backend, avoiding 401s from valid API keys.
- Sandbox: keep workspace skill mounts read-only for remote container-cwd file operations and reject symlinked skill roots before creating protected overlays. (#85591) Thanks @jason-allen-oneal.
- Scripts/Windows: route remaining QA, release, profile, and live-media `pnpm` launches through the managed runner so native Windows avoids brittle `.cmd` execution and shell-argv warnings.
- Release: align generated config/API baselines and the meeting-notes plugin version so release preflight stays green on native Windows.
- Install/Windows: run Git hook setup through a Node prepare helper so native Windows installs no longer print POSIX shell errors.
- Checks/Windows: chunk and serialize extension oxlint shards on native Windows so changed gates avoid Go-backed linter memory spikes.
- Release/Windows: run installed `openclaw.cmd` verification through explicit `cmd.exe` wrapping so npm prepublish/postpublish checks avoid Node shell-argv warnings.
- Release/Windows: run release-check npm pack/install/root probes through the shared npm runner so native Windows avoids bare `npm` lookup and `.cmd` shell-argv handling.
- Release/Windows: run cross-OS release check `.cmd` shims through explicit `cmd.exe` wrapping so native Windows install and gateway probes avoid Node shell-argv handling.
- Control UI/Windows: run i18n Pi, npm, and pnpm helper commands through explicit Windows runners so native Windows translation sync avoids brittle `.cmd` launches.
- Scripts/Windows: run the Z.AI fallback repro through the shared pnpm runner so native Windows avoids raw `.cmd` launches.
- Codex/Windows: run app-server protocol formatting through the shared pnpm runner so native Windows avoids raw `.cmd` launches.
- Plugins/Windows: run plugin npm package staging through the shared npm runner so native Windows release checks avoid bare `npm` lookup and `.cmd` shell-argv handling.
- Checks/Windows: route full `pnpm check` stage commands through the managed child runner so Windows avoids Node shell-argv deprecation warnings there too.
- Agents/fs: allow workspace-only host write/edit tools to write through in-workspace symlink directory parents while preserving outside-workspace symlink rejection. Fixes #84696. Thanks @garbagenetwork.
- Checks/Windows: run managed child commands through explicit `cmd.exe` wrapping instead of Node shell mode with argv, avoiding Node 24 subprocess deprecation warnings during changed checks.
- Gateway: omit internal stream-error placeholder entries from agent prompt history so failed assistant turns are not replayed as model-authored text. (#85652) Thanks @anyech.
- Sessions: enforce the session write-lock max-hold policy during lock acquisition so long-held locks can be reclaimed before the stale-lock window. (#85764) Thanks @njuboy11.
- Sessions/status: preserve user-facing model, fallback, usage, and cost attribution when internal subagent handoff runs use fallback models. (#85726, fixes #85082) Thanks @brokemac79.
- Install/update: honor `OPENCLAW_HOME` when deriving default dev checkout and installer onboarding paths, while keeping explicit `OPENCLAW_GIT_DIR` and `OPENCLAW_CONFIG_PATH` overrides authoritative. Fixes #54014. Thanks @robertPiro.
- Models: prune retired Groq, GitHub Copilot, OpenAI, xAI, and old Claude catalog entries, with doctor migration to upgrade existing configs to current provider refs.
- Plugins/Gateway: treat non-empty return values from plugin gateway method handlers as successful responses so `openclaw gateway call` no longer times out after completed plugin work. Fixes #59470. Thanks @HTMG23.
- Doctor/update: recognize junction-backed source checkouts as git installs by comparing canonical paths before showing package-manager update guidance. Fixes #82215. Thanks @igormf.
- Channels: honor `/verbose on` for tool/progress summaries across direct chats, groups, channels, and forum topics while preserving quiet default behavior. (#85488) Thanks @kurplunkin.
- Update: keep the detached gateway restart handoff best-effort when the restart script process cannot be spawned. (#83892) Thanks @davinci282828.
- Windows/config: skip POSIX login-shell env fallback on native Windows so startup no longer warns about missing `/bin/sh`. Fixes #84795. Thanks @JIRBOY.
- Telegram: persist the prompt-context message cache through plugin state and record bot-authored replies after sends and draft streaming so later turns can include prior assistant replies without relying on the JSON sidecar. (#85231) Thanks @keshavbotagent.
- Agents/subagents: keep Codex persona and user workspace files turn-scoped so native Codex subagents inherit only shared tool guidance by default. (#85811) Thanks @lastguru-net.
- CLI/skills: show an all-ready note with next-step commands when skill setup has no missing dependencies to install. (#85032) Thanks @aniruddhaadak80.
- Microsoft Foundry: route DeepSeek V4 Pro and Flash models through the Foundry Responses API while keeping older DeepSeek models on their existing path. (#85549) Thanks @roslinmahmud.
- Status/usage: show configured cost estimates for AWS SDK models in full usage output while keeping token-only usage replies cost-free. (#85619) Thanks @ItsOtherMauridian.
- Agents/OpenAI Responses: retry non-visible reasoning-only turns for OpenAI Responses API families instead of treating them as empty failed turns. (#85603) Thanks @SebTardif.
- Directive tags: preserve message and content-part object identity when display stripping makes no directive-tag changes. (#85682) Thanks @willamhou.
- Telegram: send local `path`/`filePath` and structured attachment media from `sendMessage` actions instead of dropping them or sending text-only messages. (#85219) Thanks @keshavbotagent.
- Sessions/status: show the estimated context budget when fresh provider usage is unavailable and clear stale estimates across session resets and compaction boundaries. (#84830) Thanks @giodl73-repo.
- Gateway/config: pin relative `OPENCLAW_STATE_DIR` overrides to an absolute path at startup so later working-directory changes cannot retarget gateway state. (#52264) Thanks @PerfectPan.
- Checks/Parallels: make changed-lane scripts, shrinkwrap generation, and Parallels package smoke host commands run through native Windows-safe paths and `npm`/`pnpm` shims.
- Release/package: run npm release, prepublish, and postpublish verification through Windows-safe npm command shims so native Windows checks can execute `npm.cmd` instead of treating it as a binary.
- Agents/harness: pass CLI runtime aliases through harness selection so provider-owned CLI aliases no longer get rejected before reaching the right runtime. (#85631) Thanks @potterdigital.
- Secrets: show the irreversible apply warning after interactive `secrets configure` confirmation so confirmed migrations still get the final safety prompt. (#85638) Thanks @alkor2000.
- Agents/CLI output: ignore cumulative Claude `stream-json` result usage when assistant usage events are present, preventing inflated cache-read accounting. (#85625) Thanks @zhouhe-xydt.
- CLI: keep `waitForever()` alive by leaving its keep-alive interval ref'd so the public helper no longer exits immediately with Node's unsettled-await code. (#85694) Thanks @m1qaweb.
- Agents/bootstrap: guard bootstrap name checks against missing file names so malformed bootstrap entries warn and truncate instead of crashing. Fixes #85523. (#85615) Thanks @zhouhe-xydt.
- CLI/tasks: reject partially numeric `openclaw tasks audit --limit` values so audit limits must be real positive integers instead of accepting strings like `5abc`. (#84901) Thanks @jbetala7.
- Status/diagnostics: bound deep Docker audit probes so `openclaw status --deep` reports slow container checks instead of hanging behind unbounded inspection. (#85476) Thanks @giodl73-repo.
- Providers/Anthropic: migrate 1M context handling to GA-capable Claude 4.x models by sizing eligible models at 1M without the retired `context-1m-2025-08-07` beta, ignoring that retired beta in older configs, and preserving OAuth-required Anthropic beta headers. (#45613) Thanks @haoyu-haoyu.
- Cron/Telegram: parse forum-topic delivery targets through the Telegram plugin instead of cron core, including `:topic:` and `:topicId` forms for announce delivery. Thanks @etticat.
- Twitch: keep stale message-handler cleanup callbacks from removing newer handler registrations for the same account, preserving inbound message delivery after reconnects. Fixes #83888. (#85425) Thanks @alkor2000.
- Control UI/chat: keep light-mode model, thinking, config, and agents select arrows visible without tiling background icons. Fixes #85713. Thanks @Linux2010.
- Memory/LanceDB: expose public memory artifacts through the active memory provider bridge so memory-wiki imports durable memory files, daily notes, dream reports, and event logs without depending on memory-core internals. Fixes #83604. (#85060) Thanks @brokemac79.
- Crabbox: keep AWS hydration compatible with local Actions replay by inlining the hydrate workflow's Node/pnpm setup instead of invoking repo-local composite actions.
- Agents/subagents: simplify native sub-agent completion handoff so children report their latest visible assistant result to the requester without using `message`, while keeping parent-owned message-tool delivery policy intact. Fixes #85070. (#85089) Thanks @brokemac79.
- Docker setup: stop printing the Gateway bearer token in setup logs and printed follow-up commands.
- Gateway: defer channel account startup work until HTTP readiness and remove startup model prewarm, avoiding startup event-loop stalls and timer-delay warnings.
- Models/perf: reuse plugin metadata during models.json planning, keep bundled catalog augmentation manifest/static, and use static provider catalogs for metadata-only startup discovery so provider model normalization, auth discovery, and Gateway startup metadata do not reload broad plugin runtimes.
- Agents: let embedded compaction fallback retries proceed when PI-compatible candidates do not need agent harness plugin preparation.
- Agents/tools: honor configured custom provider API keys when deciding whether media, image-generation, video-generation, music-generation, and PDF tools are available. (#85570)
- StepFun: stop advertising stale generic API key auth choices so onboarding only offers runtime-backed Standard and Step Plan choices.
- Diagnostics: keep OpenTelemetry log bodies behind explicit content capture and scrub scoped agent-session keys from OpenTelemetry and Prometheus labels while preserving bounded queue-lane prefixes.
- Windows installer: fail Git checkout installs when `pnpm install` or `pnpm build` fails instead of writing a wrapper to a missing CLI build.
- Sessions: surface previous-transcript archive failures during `/new` rotation so disk rename errors are logged instead of silently hiding stranded transcript files. Fixes #81984. (#85586, from #82081) Thanks @0xghost42.
- TUI/agents: mirror internal-ui message-tool replies into final chat output so message-tool-only agents remain visible in `openclaw tui`. Fixes #85538. Thanks @danpolasek.
- Gateway/TUI: preserve source-reply metadata through reply normalization and emit message-tool-only agent replies over the live chat stream so `openclaw tui` renders Codex replies without waiting for a history refresh. Thanks @shakkernerd.
- Codex/TUI: keep long source-reply runs alive after Codex reasoning completes so delayed visible `message` calls can still reach `openclaw tui`. Thanks @shakkernerd.
- TUI: keep quiet active runs busy after the response watchdog notice instead of reopening the prompt and encouraging duplicate submissions while the backend turn is still running. Thanks @shakkernerd.
- Agents: preserve the latest assistant thinking blocks while stripping invalid replay signatures from older turns, and retry Anthropic thinking failures without thinking replay. Fixes #85557. Thanks @bryanbaer.
- Agents: keep parallel OpenAI-compatible tool-call deltas in separate argument buffers so interleaved tool calls no longer corrupt streamed arguments. (#82263) Thanks @luna-system.
- Telegram: avoid false pairing prompts after transient pairing-store read failures while preserving configured `allowFrom` and per-DM pairing authorization. (#85555)
- Memory/doctor: report missing or unusable QMD workspace directories as workspace failures instead of generic binary failures. (#63167) Thanks @sercada.
- Debug proxy: record CONNECT client-socket errors and destroy the paired upstream socket so abrupt client disconnects no longer leak tunnel resources. (#82444) Thanks @SebTardif.
- Diffs: continue hydrating later diff cards when one card fails so a single broken card no longer blanks the whole diff viewer. (#84775) Thanks @cosmopolitan033.
- Mac app: use the native settings sidebar window chrome so the sidebar toggle stays on the left and content no longer clips under oversized titlebar padding.
- QA-Lab/Codex: bundle auth/plugin fixture imports for flow scenarios and let terminal async media tools end Codex app-server turns without timing out. (#80397, refs #80323) Thanks @100yenadmin.
- WhatsApp: persist inbound message delivery state through plugin state before dispatch and delay read receipts until handler completion, so retryable failures can redeliver without adding a plugin-local disk cache. Thanks @samzong.
- Gateway/agents: preserve fresh session overrides and metadata when stale cached agent-session entries race with store updates, so subagent model/provider overrides and routing policy survive concurrent writes. (#19328) Thanks @CodeReclaimers.
- Control UI/chat: keep chat session search inline with the session selector so the header no longer shows a duplicate standalone search row.
- Control UI/chat: collapse focused-mode header chrome and suppress hidden-header scroll updates so focus mode no longer jumps while scrolling. Thanks @amknight.
- Codex app-server: restart the native app-server and retry once when server-side compaction times out, so preflight compaction stalls recover instead of failing every dispatch. (#85500)
- OpenAI video: honor configured provider request private-network opt-in for local/custom video endpoints so explicitly trusted mock and self-hosted providers are not blocked. Thanks @shakkernerd.
- OpenAI video: send uploaded video edit requests to the documented `/videos/edits` endpoint with a `video` file instead of posting MP4 references to `/videos`. Thanks @shakkernerd.
- Agents/channels: preserve message-tool delivery evidence through gateway agent completion handoffs so successful generated media sends are not followed by false failure messages. Thanks @shakkernerd.
- CLI/update: repair managed npm plugin `openclaw` peer links during post-core convergence and reject stale or wrong-target peer links before restart. (#83794) Thanks @fuller-stack-dev.
- CLI/agents: default new omitted-account bindings to all accounts when the channel has multiple configured accounts, and clarify account-scope docs. (#49769) Thanks @Gcaufy.
- Codex app-server: let authorized `/codex` control commands such as `/codex detach` escape plugin-owned conversation bindings while keeping unknown or unauthorized slash text routed to the bound plugin. Fixes #85157. (#85188) Thanks @TurboTheTurtle.
- Auto-reply/models: keep `/models` browse replies fast by sharing the bounded read-only catalog path with Gateway model listing. (#84735) Thanks @safrano9999.
- Browser/Doctor: read macOS Chrome app bundle versions from `Info.plist` before spawning Chrome and extend the fallback version probe timeout, avoiding false cold-cache warnings from Gatekeeper latency. Fixes #85418. Thanks @davidcittadini.
- Codex app-server: disable native Code Mode when the effective exec host is `node` and keep OpenClaw `exec`/`process` available, so `/exec host=node` routes shell commands through the selected node instead of the gateway. Fixes #85012. (#85090) Thanks @sahilsatralkar.
- Agents: bound embedded auto-compaction session write-lock watchdogs to the compaction timeout instead of the full run timeout, so stuck compaction cannot hold the live session lock for the whole run window. (#84949) Thanks @luoyanglang.
- Gateway/agents: return phase-aware `agent.wait` timeout attribution and only cool auth profiles on provider-started timeouts. Refs #65504. Thanks @100yenadmin.
- Gateway/systemd: launch managed update handoff helpers in a transient user scope so systemd-supervised Update Now flows survive the gateway unit restart. Fixes #84068.
- Gateway: defer provider auth-state prewarm until after startup readiness so early gateway tool/session requests are not blocked by provider auth discovery. (#85272) Thanks @dutifulbob.
- Gateway/models: coalesce provider auth-state rewarms after auth-profile failures and log event-loop delay for warm/rewarm work, so provider auth bursts no longer stack full auth sweeps behind channel replies.
- Gateway/models: stop cancelled provider auth-state prewarms from continuing full provider sweeps, so reload and auth-failure bursts no longer keep startup busy.
- Agents/Codex: show the first plan update as a transient chat status notice without counting it as final assistant content.
- CLI/update: walk the macOS process ancestry and honor the inherited Gateway runtime PID before package updates stop the managed Gateway service, so nested in-band updater children can refuse instead of killing the LaunchAgent-supervised Gateway that owns them. Fixes #85120.
- Gateway/LaunchAgent: wait for launchd reload bootout to finish and fall back to kickstart when bootstrap races, so reload handoff does not leave the service deregistered. Fixes #84630. (#84641) Thanks @NianJiuZst.
- Gateway/LaunchAgent: treat a concurrent launchd bootstrap as a successful restart when the service is already loaded, avoiding false macOS Gateway restart failures. Fixes #84721. (#84722) Thanks @googlerest.
- Gateway/service: include the active `openclaw` command bin directory in managed service PATH generation and doctor audit expectations for npm-global macOS installs. Fixes #84201. (#84475) Thanks @jbetala7.
- Control UI/chat: disable the thinking selector for known non-reasoning models instead of showing duplicate Off choices. Fixes #84069. Thanks @DrippingMellow.
- Memory: expand `~` in configured extra memory paths before resolving them, so home-relative folders are not treated as workspace-relative. Fixes #58026. Thanks @stadman.
- Skills: treat `openclaw.os: macos` as Darwin when checking skill requirements, so macOS-only skills no longer report as missing on macOS hosts. Fixes #61338. Thanks @Jessecq1995.
- Control UI/logs: strip ANSI escape sequences from displayed Gateway log messages so color codes no longer appear as raw text. Fixes #64399. Thanks @guguangxin-eng.
- Docker: pre-create the workspace and auth-profile config mount points with `node` ownership so first-run named volumes do not start root-owned. Fixes #85076. Thanks @Noerr.
- Diagnostics/OTel: drop snake_case diagnostic id attributes alongside camelCase ids so exported telemetry cannot leak run, session, message, chat, trace, or tool-call identifiers. (#72645) Thanks @Lion0710.
- CLI/update: preserve managed Gateway service environment during package cutovers so macOS LaunchAgent repair/restart reads the pre-update service state instead of caller shell state. (#83026)
- Agents/providers: honor per-model `api` and `baseUrl` overrides in custom provider auth hooks and transport selection. Fixes #80487. (#80488) Thanks @huveewomg.
- Gateway/restart: eager-load the lifecycle runtime before in-place upgrade signal handling so package replacement does not deadlock restart imports. (#84890) Thanks @myps6415.
- CLI/update: start managed Gateway update handoff helpers from a stable existing directory and tolerate deleted cwd/package roots during macOS LaunchAgent handoff. Fixes #83808. (#83875) Thanks @jason-allen-oneal.
- Skills: watch each shared skill directory once across agent workspaces instead of once per agent, preventing file-descriptor exhaustion (`EMFILE`) that disposed bundle-mcp processes and stalled sessions on multi-agent gateways. Fixes #84968. (#85130) Thanks @openperf.
- Release/security: keep generated npm shrinkwrap package versions inside the pnpm lock graph so published package locks cannot bypass pnpm dependency age and override policy.
- Cron: honor `cron.retry.retryOn: ["network"]` for common network error codes such as `EAI_AGAIN`, `EHOSTUNREACH`, and `ENETUNREACH`.
- Gateway chat: broadcast returned agent-run error payloads after an agent starts so ACP/WebChat clients receive terminal idle-timeout errors. Fixes #84945.
- Gateway chat display: preserve OpenAI-compatible `prompt_tokens`, `completion_tokens`, and `total_tokens` usage fields in sanitized chat history so llama.cpp sessions keep context counts. Fixes #77992. Thanks @MarTT79.
- Dashboard/CLI: allow macOS browser launching through `open` even when SSH environment variables are present, while preserving Linux SSH no-display protection. Fixes #67088. Thanks @theglove44.
- Codex app-server: keep native web search observations out of mirrored chat transcripts while preserving available action query metadata in tool progress telemetry. Fixes #85109. Thanks @ugitmebaby.
- OpenCode Go: strip unsupported Kimi reasoning replay fields before provider requests so repeated `kimi-k2.6` turns do not fail schema validation. Fixes #83812. Thanks @Sleeck.
- Browser/CDP: add a WSL2 portproxy self-loop hint when Chrome DevTools endpoints accept connections but return an empty HTTP reply. Fixes #59209. Thanks @Owlock.
- Agents/tools: add bounded tool-policy audit log entries that identify which allow/deny rule removed tools or blocked a sandboxed tool call. Fixes #55801. Thanks @justinjkline.
- CLI/logs: read implicit local Gateway logs through the passive backend client path so `openclaw logs --follow` does not register as a paired device, and use the active Linux systemd journal instead of stale configured-file fallbacks when live local RPC is unavailable. Fixes #83656 and #66841.
- Agents/OpenAI: preserve structured provider error code, type, and redacted body metadata on boundary-aware transport failures.
- Doctor/Codex: point native Codex asset warnings at the canonical `openclaw migrate plan codex` preview command. Fixes #84948. Thanks @markoa.
- CLI/models: make `capability model auth logout --agent` remove auth profiles from the selected non-default agent store. Fixes #85092. Thanks @islandpreneur007.
- Gateway/models: reuse prepared provider auth metadata during model-listing auth checks so repeated lookups avoid broad plugin discovery while preserving synthetic local auth.
- CLI/status: suppress systemd user-service setup hints when `openclaw status --deep` can already reach a running Gateway RPC service. Fixes #85094. Thanks @islandpreneur007.
- CLI/devices: recover local approval when a same-device repair request replaces the request ID being approved.
- CLI/agents: retry transient normal-close Gateway handshakes before falling back to embedded `openclaw agent` execution.
- CLI/update: keep managed Gateway service stop/restart status lines out of `openclaw update --json` stdout so package-update automation can parse the JSON payload.
- Plugins: resolve OpenClaw plugin SDK subpaths for native external plugin runtimes without mutating package installs or broadening process-wide module resolution.
- Agents/OpenAI: preserve Responses and Chat Completions `reasoning_tokens` usage metadata without double-counting it in aggregate output tokens. (#85319)
- Control UI/chat: convert pasted `data:image/...;base64,...` clipboard text into an image attachment instead of dumping the payload into the composer. Fixes #62604. Thanks @cpwilhelmi.
- Providers/Gemini: strip fractional seconds from web-search time range filters so Gemini accepts freshness-bound search requests. (#85071) Thanks @Noerr.
- OpenAI Codex: preserve image input support for sparse `openai-codex/gpt-5.5` catalog rows. (#85095) Thanks @sercada.
- CLI/models: add a piped or pasted API-key path for OpenAI Codex auth and warn when API keys are pasted into token-mode auth. (#85533) Thanks @joshavant.
- Telegram: dead-letter missing-harness isolated ingress failures so a poisoned spooled update no longer blocks later same-lane messages. Fixes #85470. (#85605) Thanks @joshavant.
- Plugins/discovery: strip `-plugin` package suffixes when deriving plugin id hints so package names line up with manifest ids. (#85170) Thanks @JulyanXu.
- Tlon: stop advertising a non-existent agent tool contract in the plugin manifest.
- Telegram: preserve fenced code block languages through Markdown rendering so Telegram receives `language-*` code classes. (#85209) Thanks @leno23.
- Windows installer: run npm and Corepack command shims from a Windows-local directory so installs launched from WSL2 UNC paths do not fail before OpenClaw is installed.
- Windows updates: roll back git-backed updates to the previous checkout when dependency install, build, UI build, or doctor repair fails.
- Windows installer: persist user-local portable Git on PATH and activate the repo-pinned pnpm version for git-backed installs and updates.
- Windows installer: bootstrap a user-local portable Node.js when native Windows has no Node and no winget, Chocolatey, or Scoop, so first-run installs can continue on raw hosts.
- Windows installer: extract the downloaded portable Node.js directory with native `tar` before falling back to .NET zip extraction, avoiding PowerShell 5.1 archive and path-length failures.
- Agents/heartbeat: route single-owner `session.dmScope=main` direct-message exec and cron event wakes back to the agent main session so async completions no longer strand context in orphan direct-DM queues. Fixes #71581. (#83743) Thanks @Kaspre.
- Agents/code-mode: expose outer code-mode `exec` source through the `command` hook alias with `toolKind`/`toolInputKind` discriminators so exec-shaped policies can distinguish code-mode cells. (#83483) Thanks @Kaspre.
- Agents/code mode: return structured timeout and runtime-unavailable error codes for known worker failures. Fixes #83389. (#83444) Thanks @Kaspre.
- QA-Lab: isolate multi-scenario suite workers when scenarios need startup config patches, preventing message-routing config from leaking into unrelated scenarios.
- QA-Lab: make the commitments heartbeat-target-none scenario request an immediate heartbeat instead of waiting for the next scheduled heartbeat.
- Codex/Plugin SDK: deliver Codex-native subagent completions through a generic harness task runtime so harness-backed plugins can mirror durable task lifecycle and completion delivery without Codex-specific SDK imports. (#83445) Thanks @bryanpearson.
- Gateway CLI: surface local post-challenge connect assembly failures immediately instead of waiting for the wrapper timeout. Fixes #68944. (#85253) Thanks @samzong.
- Messages: strip unsupported web-search citation control markers from outbound replies before they reach WebChat or external channels. Fixes #85193. (#85204) Thanks @neeravmakwana.
- Agents/exec: treat denied exec approvals as terminal instead of feeding them back into agent follow-up work, and recognize Chinese stop phrases in abort handling. Fixes #69386. (#85194) Thanks @samzong.
- CLI/agents: abort accepted Gateway-backed `openclaw agent` runs on SIGINT/SIGTERM so cron and supervisor timeouts do not leave remote agent work alive. Fixes #71710. (#84381) Thanks @Kaspre.
- Codex app-server: retry replay-safe stdio client-close turns once using structured failure metadata, while surfacing idle `turn/completed` timeouts instead of blindly replaying active shared-server turns. Thanks @VACInc.
- Codex app-server: reject command overrides that embed Node or package-manager arguments and point users to `appServer.args`, so Windows startup avoids shell parsing failures. (#84417) Thanks @TurboTheTurtle.
- Agents/Copilot: drop unsafe GitHub Copilot Responses reasoning replay items before send so Telegram direct sessions no longer fail on overlong replay IDs. Fixes #85197. (#85198) Thanks @galiniliev.
- UI: add accessible tooltips to the topbar color-mode buttons so System, Light, and Dark choices are labeled on hover and focus. (#85227) Thanks @amknight.
- Control UI: keep the chat session picker from hiding older or cross-agent configured conversations while preserving the bounded configured-agent refresh. (#85211) Thanks @amknight.
- Agents/Anthropic: preserve unsafe integer tool-call input values in streamed Anthropic tool-use JSON, preventing Discord-style IDs from being rounded before dispatch. Fixes #47229. (#83063) Thanks @leno23.
- Agents/Codex: estimate tool-heavy prompt pressure at the LLM boundary before provider submission, so persistent sessions compact before overflowing context windows. (#85541) Thanks @fuller-stack-dev and @joshavant.
- Agents/hooks: wait for local one-shot CLI and Codex `agent_end` plugin hooks before process cleanup so terminal observability flushes reliably. (#85007)
- Providers/Google: preserve Gemini 3 cron `thinkingDefault: "low"` when stale catalog metadata says `reasoning:false`, so scheduled runs keep provider-supported thinking instead of downgrading to off. (#85185) Thanks @neeravmakwana.
- CLI/agents: allow `openclaw agent --session-key` to target explicit session keys, including agent-scoped legacy keys. (#85121) Thanks @Kaspre.
- Auto-reply/ACP: wait for same-channel block reply delivery before starting tool work, while still honoring ACP dispatch aborts so stopped turns do not wait on slow channel sends. (#83722) Thanks @IWhatsskill.
- Codex/ACP: mark required child-run completions that only report progress, omit a final deliverable, or fail requester delivery as blocked while preserving real final reports. (#85110) Thanks @IWhatsskill.
- Channels: treat bare abort messages such as `stop`, `abort`, and `wait` as immediate control commands in inbound debounce paths so stop requests are not delayed behind pending message coalescing. (#83348) Thanks @IWhatsskill.
- Channels/message tool: resolve configured external channel plugins during in-agent channel selection, so `openclaw agent --local` message-tool sends no longer report an available channel as unavailable. (#85022) Thanks @Kaspre.
- Agents/heartbeat: honor group/channel `message_tool` visible-reply policy and model-specific Codex runtime config for scheduled heartbeat runs, so failed internal tool output stays private. Fixes #85310. (#85357) Thanks @neeravmakwana.
- Gateway/ACP: close child ACP sessions spawned via `sessions_spawn` when their parent session is reset or deleted, instead of leaving orphaned `claude-agent-acp` processes that accumulate and exhaust memory. Fixes #68916. (#85190) Thanks @openperf.
- Codex app-server: block native execution paths when OpenClaw exec resolves to a node host while preserving the first-party CLI node binding path. Fixes #85012. (#85534) Thanks @joshavant.
- Diagnostics: bound cleanup timeout detail logs, emit drop summaries when async diagnostic bursts exceed the queue cap, and surface async queue drops through diagnostic telemetry.
- Agents/subagents: surface blocked child-run completions as errors instead of successful subagent finishes. (#80886) Thanks @TurboTheTurtle.
- Context engines: fail closed with a descriptive error when the selected agent runtime cannot satisfy declared context-engine host requirements.
- Agents/Pi: treat accepted embedded `sessions_spawn` child-session handoffs as terminal progress so parent turns no longer report false non-deliverable failures. (#85054) Thanks @samzong.
- CLI/models: resolve `openclaw models set` aliases from the runtime config while keeping authored aliases ahead of runtime-only defaults. (#83262) Thanks @IWhatsskill.
- Doctor: show personal Codex CLI asset notices as info instead of warnings. Fixes #84859.
- WhatsApp: update Baileys to `7.0.0-rc13` and drop the obsolete logger type patch.
- CLI/update: pre-pack GitHub/git package update targets before the staged npm install, restoring `openclaw update --tag main` for one-off package updates. (#81296) Thanks @fuller-stack-dev.
- Gateway: mirror successful same-source message-tool sends into session transcripts so delivered replies stay in later history/context. (#84837) Thanks @iFiras-Max1.
- Media generation: keep image, music, and video completion delivery from duplicating or losing task ownership when generated media finishes through active session replies. (#84006) Thanks @fuller-stack-dev.
- CLI/doctor: remove stale bundled plugin load paths from old versioned OpenClaw package roots after pnpm/npm upgrades. Fixes #58626. Thanks @solink7.
- Infra/json: retry transient `File changed during read` races while loading JSON state so config and state reads recover instead of failing the turn. (#84285)
- Plugins/providers: fail closed for workspace provider plugins during setup-mode discovery unless explicitly trusted, preventing untrusted workspace plugin code from running during provider setup. (#81069) Thanks @mmaps.
- Providers/Ollama: resolve configured Ollama Cloud `OLLAMA_API_KEY` markers to the real discovery key so cloud provider entries keep authenticated model catalog access. (#85037)
- Discord: keep persistent component registry fallback warnings actionable by forwarding structured error and cause metadata through the runtime logger. Fixes #84185. (#84190) Thanks @100menotu001.
- Gateway/sessions: preserve compatible session auth profile overrides when switching models within the same provider, including provider-auth aliases. Fixes #81837. (#81886) Thanks @TurboTheTurtle.
- Gateway/status: surface inbound delivery telemetry counters and transport-liveness warnings in `openclaw status --all`. Fixes #49577. (#72724)
- Docker: prune package-excluded plugin source workspaces and dependency closures so runtime images do not keep packages for plugins that were not opted in.
- Providers/Ollama: treat Docker/OrbStack host aliases as local Ollama endpoints so `ollama-local` marker auth works when OpenClaw runs inside a VM/container and Ollama runs on the host. Fixes #84875.
- QA-Lab: keep explicitly searchable/deferred OpenClaw dynamic tool rows report-only by default so tool-coverage gates do not treat mock discovery gaps as hard product failures. (#80319) Thanks @100yenadmin.
- Agents/config: keep non-Google provider model refs from being rewritten by Google Gemini preview-id normalization. (#84762) Thanks @zhangguiping-xydt.
- Installer: require a real controlling terminal before launching onboarding so headless `curl | bash` installs finish cleanly after installing the CLI.
- Agents/Codex: promote a completed final assistant response when a prompt timeout races Codex app-server completion instead of returning an empty timeout envelope. Refs #84516.
- Codex app-server: keep interrupted turn statuses from being treated as OpenClaw aborts by themselves, so tool-only turns remain eligible for no-visible-answer recovery. Fixes #84492.
- Agents: cap heartbeat model bleed context hints by the stored session window when runtime model metadata is unavailable, so overflow recovery advice does not suggest a larger window than the active session actually has.
- Control UI/Web Push: use `https://openclaw.ai` as the generated default VAPID subject instead of the old localhost mailbox so iOS PWA push setup uses an Apple-acceptable subject when `OPENCLAW_VAPID_SUBJECT` is unset. Fixes #83134. (#83317) Thanks @IWhatsskill.
- Control UI: distinguish inherited thinking-off settings from explicit Off selections so the thinking selector no longer shows two identical Off rows. (#85223) Thanks @amknight.
- Agents/Pi: keep embedded session transcript writes from tripping false takeover detection after packaged npm onboarding agent turns.
- Codex/TUI: surface Codex-native post-turn compaction failures instead of continuing uncompacted, and keep successful native compaction serialized before local idle/next-turn handling. Fixes #84305. (#85160) Thanks @joshavant.
- Memory/search: stop recall tracking from writing dreaming side-effect artifacts when `dreaming.enabled=false`, while preserving normal search results. Fixes #84436. (#84444) Thanks @NianJiuZst.
- Diffs: render viewer toolbar icons from a closed icon-name map instead of HTML strings, removing the toolbar icon XSS sink. (#83955) Thanks @tanshanshan.
- QA: keep `pnpm qa:e2e` self-check runs inside the private QA runtime envelope even when inherited shell env disables bundled plugins.
- Update/doctor: prune stale local bundled plugin install records that point at old compiled bundled output so current bundled plugin schemas win after upgrade. (#84863) Thanks @fuller-stack-dev.
- Providers/Ollama: preserve native Ollama tool-call IDs across assistant replay so Gemini over Ollama Cloud can keep its hidden function-call thought-signature handle.
- Discord: keep session recovery and `/stop` abort ownership on the source dispatch lane while bound ACP turns continue routing to their target session, so stalled pre-run work and late replies are cleared instead of leaking after stop. Fixes #84477. (#85100) Thanks @joshavant.
- Discord/voice-call: keep forced realtime voice consult diagnostics in debug logs instead of agent prompts, so callers do not hear OpenClaw policy text when the provider misses `openclaw_agent_consult`. (#84411) Thanks @fuller-stack-dev.
- Codex app-server: mark missing turn completion after observed execution as replay-unsafe and release the session so follow-up turns can run. Fixes #84076. (#85107) Thanks @joshavant.
- Codex app-server: give visible `message` dynamic tool sends a longer timeout budget so slow channel delivery can return its own result or error instead of hitting the 30-second Codex wrapper. (#85216) Thanks @amknight.
- Codex app-server: add a dedicated post-tool raw assistant completion idle timeout config so trusted heavy turns can wait longer after tool handoff without weakening final assistant release.
- Matrix: keep explicitly configured two-person rooms on the room route before stale `m.direct` or strict two-member DM fallback can bypass mention gating. Fixes #85017. (#85137) Thanks @joshavant.
- Agents/subagents: require explicit subagent allowlist targets to be configured agents so stale deleted-agent ids are omitted from `agents_list` and rejected by `sessions_spawn`. Fixes #84811. (#85154) Thanks @joshavant.
- PDF tool: time out idle remote PDF body reads after 120 seconds so stalled remote documents return an error instead of wedging the session. Fixes #68649. (#84768) Thanks @luoyanglang.
- Diagnostics/OpenTelemetry plugin: suppress handled OTLP exporter promise rejections so collector shutdowns no longer crash the Gateway. (#81085) Thanks @luoyanglang.
- Agents/exec: omit raw command text and env values from denied exec failure logs while keeping safe correlation metadata. Fixes #85049. (#85140) Thanks @joshavant.
- Media-understanding: restore the 4096-token default for image descriptions so reasoning-capable vision models no longer truncate before returning text, while preserving smaller model caps. (#84932) Thanks @scotthuang.
- Media/audio: skip empty structured sherpa-onnx transcripts instead of treating the raw JSON payload as spoken text. (#84667) Thanks @TurboTheTurtle.
- Agents/exec: preserve inherited XDG base-directory environment values for subprocesses while still rejecting agent-supplied XDG overrides. Fixes #84854. (#85139) Thanks @joshavant.
- Node/Linux: keep `OPENCLAW_GATEWAY_TOKEN` out of generated systemd unit files by writing node service token values to a node-specific env file. (#84408)
- Memory-core/dreaming: reuse stable narrative subagent session keys per workspace and phase while keeping per-run idempotency and bounded cleanup, so stale `dreaming-narrative-*` sessions do not accumulate. Fixes #68252, #69187, and #70402. (#70464) Thanks @chiyouYCH.
- Trajectory/support: tolerate partial skill snapshot entries when building support metadata so rejected skill path scans no longer abort trajectory capture. (#71185) Thanks @lukeboyett.
- TUI: coalesce repeated idle Esc abort notices into a single `no active run xN` system row instead of appending duplicate rows.
- Telegram: honor `channels.telegram.pollingStallThresholdMs` in the default isolated polling path, restarting silent workers instead of leaving inbound updates wedged. Fixes #83950. (#84861) Thanks @joshavant.
- Telegram: dedupe replayed message dispatches by Telegram chat/message identity so isolated-ingress replays do not trigger duplicate model dispatches. Fixes #84886. (#85208) Thanks @joshavant.
- Slack: suppress reasoning payloads before reply delivery and dispatch accounting, so Slack monitor, slash-command, fallback, and direct reply paths do not leak model reasoning. Fixes #84319. (#84322) Thanks @ffluk3 and @joshavant.
- Slack: deliver native plugin approval prompts and updates when Slack native approvals are enabled, while keeping plugin approval authorization separate from exec approvers.
- Slack: keep native plugin approval prompts in the originating app conversation thread when the live Slack turn source is a `D...` conversation.
- Agents/Pi: disable the embedded pi-coding-agent runtime auto-retry so OpenClaw's own retry and failover loop does not replay failed tool calls through a nested SDK retry. Fixes #73781. (#74434) Thanks @yelog.
- CLI/perf: keep `setup --help`, `onboard --help`, and `configure --help` out of the full wizard runtime while preserving the existing help output. (#84488) Thanks @frankekn.
- CLI/perf: keep `agents --help` out of agents action/runtime imports so help, completion, and command discovery paths avoid loading the full agents runtime. (#84483) Thanks @frankekn.
- CLI/perf: keep `secrets --help` and `nodes --help` on the precomputed help path so parent help avoids loading action-heavy command runtime modules. (#84818) Thanks @frankekn.
- CLI/perf: serve `doctor`, `gateway`, `models`, and `plugins` parent help from startup metadata so common subcommand help avoids full CLI program construction. (#84786) Thanks @frankekn.
- Codex/Lossless: keep context-engine history on the canonical run session when Telegram DMs use per-peer runtime policy keys. Fixes #84936. (#84954) Thanks @neeravmakwana.
- Codex: keep heartbeat response tool schemas durable without exposing dynamic tools disabled by turn policy, so heartbeat wakeups can reuse threads while scoped tool allowlists stay enforced. (#84681) Thanks @jalehman.
- Auth/OAuth: skip the refresh adapter when a stored OAuth credential has no refresh token so agent turns fail fast on missing-key instead of waiting on the 120s refresh timeout. Thanks @romneyda.
- Auth/Codex: load legacy OAuth sidecar credentials in the embedded runner's secrets-runtime auth loaders so Telegram replies, cron-triggered turns, and other isolated sub-agent lanes can reach the existing #83312 refresh-and-rewrite migration instead of failing with `No API key found for provider "openai-codex"` until the user runs `openclaw doctor`. Thanks @Totalsolutionsync and @romneyda.
- Codex/failover: classify `deactivated_workspace` as a permanent auth failure so configured fallback models can advance when a Codex workspace is deactivated. (#55893) Thanks @litang9.
- Exec: keep configured `tools.exec.pathPrepend` entries ahead of user shell startup PATH changes on POSIX gateway runs. (#81403) Thanks @medns.
- Gateway/sessions: allow shared-secret bearer callers to read and stream session history without an explicit scope header. (#81815) Thanks @medns.
- Agents/embedded runner: classify HTML auth provider responses as `auth_html` and return a re-authentication hint instead of the CDN-blocked copy that `upstream_html` returns. Cloudflare Access login pages, nginx basic-auth challenges, and gateway login walls all produce HTML auth bodies that were previously misdiagnosed as transient CDN blocks. (#79900) Thanks @martingarramon.
- TUI/streaming watchdog: dismiss the `This response is taking longer than expected` notice as soon as a chat event for the same run arrives, so the message no longer sits next to the recovered response when the run was only briefly silent. Refs #67052, #69081 (closed), prior attempt #69026. Thanks @jpruit20 and @romneyda.
- Agents/Pi: tolerate OpenClaw-owned transcript writes while embedded prompts are released for model I/O, keeping long-running Feishu, Slack, Telegram, and cron turns from failing with false session-takeover errors. Fixes #84059. (#84250) Thanks @tianxiaochannel-oss88.
## 2026.5.20
### Changes
- Exec approvals: remove the old `cat SKILL.md && printf ... && <skill-wrapper>` allowlist compatibility path so skill files must be loaded with the read tool and only the real skill executable is auto-allowed.
- Discord: let voice sessions follow configured Discord users into voice channels, with allowed-channel checks, multi-user handoff, bounded reconciliation, and DAVE recovery preservation. (#84264) Thanks @fuller-stack-dev.
- Discord/voice: include bounded `IDENTITY.md`, `USER.md`, and `SOUL.md` profile context in realtime voice session instructions by default, with `voice.realtime.bootstrapContextFiles: []` available to disable it. (#84499) Thanks @fuller-stack-dev.
- Dependencies: bump the bundled Codex harness to `@openai/codex``0.132.0` and refresh the app-server model-list docs for the new catalog.
- CLI/policy: add the bundled Policy plugin for policy-backed channel conformance checks, doctor lint findings, and opt-in workspace repair. (#80407) Thanks @giodl73-repo.
- Agents/config: allow `agents.list[].experimental.localModelLean` so lean local-model mode can be enabled for one configured agent instead of globally. (#84073) Thanks @dutifulbob.
- Providers/xAI: add device-code OAuth login so remote and headless setups can authorize xAI without a localhost browser callback. (#84005) Thanks @fuller-stack-dev.
- Providers/OpenRouter: honor provider-level `params.provider` routing policy for OpenRouter requests, with model and agent params overriding the defaults. Thanks @amknight.
### Fixes
- CLI/tasks: include stale-running task maintenance decisions in `openclaw tasks maintenance --json` so retained and reconcile candidates explain backing-session, cron, CLI, and wedged-subagent state. (#84691) Thanks @efpiva.
- Codex app-server: keep system-prompt reports working when bootstrap hooks provide workspace files with only a path and content, so hook-supplied SOUL/IDENTITY/TOOLS/USER context still reports injected characters correctly. (#84736) Thanks @JARVIS-Glasses.
- Providers/MiniMax music: stop advertising `durationSeconds` control and remove prompt-injected duration hints, so `music_generate` reports MiniMax duration as an unsupported override instead of suggesting MiniMax can enforce track length. Fixes #84508. Thanks @neeravmakwana.
- Doctor: warn when sandbox tool policy hides configured MCP server tools before provider requests. (#84699) Thanks @nxmxbbd.
- WhatsApp: update Baileys to `7.0.0-rc12`.
- Build: suppress per-locale `rolldown-plugin-dts:fake-js` CommonJS dts warnings emitted while bundling the intentionally-inlined `zod/v4/locales/*.d.cts` files, so `pnpm build` output stays readable after the 0.25.1 plugin bump. Thanks @romneyda.
- CLI/nodes: route lazy plugin-registration logs to stderr for JSON-mode `openclaw nodes` commands so stdout stays parseable. (#84684) Thanks @TurboTheTurtle.
- Approvals: route manual `/approve` decisions through the trusted approval runtime so active exec and plugin approvals no longer look unknown or expired.
- Mac app: update the About settings copyright year to 2026. (#84385) Thanks @pejmanjohn.
- Dependencies: update `@openclaw/fs-safe` to `0.2.7` so OpenClaw's default Python-helper-off policy keeps best-effort Node write fallbacks for private stores, secret writes, run logs, and media attachments on Linux/macOS.
- Infra/secrets: restore the fail-closed contract for `tryReadSecretFileSync` so credential loaders that pass `rejectSymlink: true` (Telegram, LINE, Zalo, IRC, Nextcloud Talk tokens) refuse symlinked credential files instead of silently accepting them, and the infra-state CI shard's secret-file symlink test passes again. Thanks @romneyda.
- Browser: honor the configured image sanitization limit for screenshots and labeled snapshots so browser-captured images follow the same resize policy as other image results. (#84595)
- Doctor: remove unrecognized `models.providers.*.models[*].compat.thinkingFormat` values during `doctor --fix` so stale provider model config can validate after upgrade. Fixes #77803.
- Doctor: warn when `openclaw.json` stores plaintext secret-bearing config fields, including model provider API keys and sensitive provider headers. (#84718) Thanks @lukaIvanic.
- Status: show the configured default, session-selected model, reason, clear hint, and docs link when a session remains pinned to a model that differs from `agents.defaults.model.primary`.
- WebChat: clear stale typing indicators when session change events mark the active chat run complete.
- Mac app: keep local packaging signed with a stable app identity for permission testing and fix Control UI production builds under current Vite/Highlight.js exports.
- macOS app: update the embedded Peekaboo bridge to 3.2.1 so OpenClaw-hosted UI automation works with current Peekaboo CLI capture flows.
- Cron: deliver preferred final assistant output for successful scheduled runs when trailing plain tool warnings remain in diagnostics instead of marking the run failed.
- fix(mattermost): fail closed on missing channel type [AI]. (#84091) Thanks @pgondhi987.
- CLI: keep the private QA subcommand out of exported command descriptors unless `OPENCLAW_ENABLE_PRIVATE_QA_CLI=1`, so root help and subcommand markers match runtime registration. (#84519)
- CLI/cron: bound `openclaw cron show` job lookup pagination so non-advancing or unbounded `cron.list` responses fail instead of hanging the command. Fixes #83856. (#83989)
- Agents/messages: stop message-tool-only turns after a successful source-channel `message` send while keeping transcript mirrors under the session write lock. (#84289)
- Agents: filter silent heartbeat response-tool transcript artifacts out of embedded context snapshots so later user turns are not polluted by heartbeat no-op messages. (#83477) Thanks @fuller-stack-dev.
- Agents/OpenAI: log repeated strict tool-schema downgrade diagnostics once per provider/model/tool signature, reducing duplicate debug noise while preserving `strict=false` fallback behavior. Fixes #82930. (#82933) Thanks @galiniliev.
- Agents/code mode: spell out the `exec` tool's JavaScript/TypeScript, no Node module, and catalog-bridge constraints in model-visible schema text so agents can use enabled tools without trial-and-error. (#84269) Thanks @Kaspre.
- Codex: give `image_generate` dynamic-tool calls a 120s default watchdog when no per-call or configured image timeout is set, so image generation no longer falls back to the generic 30s bridge timeout. (#84254) Thanks @moritzmmayerhofer.
- Codex: avoid duplicate dynamic tool terminal diagnostics while large diagnostic backlogs drain without blocking tool responses. (#82937) Thanks @galiniliev.
- CLI/message: include a stable top-level `messageId` in `openclaw message --json` output when channel sends return one. (#84191) Thanks @100menotu001.
- Cron: preserve legacy top-level array `jobs.json` stores when loading or adding scheduled jobs so old cron jobs are no longer treated as an empty store during upgrade. Fixes #60799. (#84433) Thanks @IWhatsskill.
- Gateway/agents: use an agent's `identity.name` in Gateway agent summaries when `agents.list[].name` is unset, so configured agent labels remain visible in clients. (#84355; refs #57835) Thanks @luoyanglang.
- Channels/replies: keep normal `/verbose` failed-tool progress compact in message-tool replies and prevent late text-only tool output from appearing after the final answer. (#84303) Thanks @VACInc.
- Plugins/hooks: apply a default 30-second timeout to `before_compaction` and `after_compaction` hooks so a hung plugin handler no longer blocks compaction completion. (#84153)
- Discord: preserve reusable presentation buttons through portable conversion and Discord component registration. (#84187) Thanks @100menotu001.
- Discord: preserve disabled presentation buttons when adapting and rendering Discord message controls. (#84188) Thanks @100menotu001.
- Twitch: add a test-only client-manager registry reset helper so non-isolated Twitch tests can clear cached managers between cases. Fixes #83887. (#84244) Thanks @hclsys.
- Cron: run main-session scheduled work on a cron-owned wake lane while preserving reply delivery context, so background cron turns no longer block human main-session chat. Fixes #82766. (#82767) Thanks @galiniliev.
- Auto-reply/slash commands: require a word boundary after the matched prefix in `parseSlashCommandActionArgs` so `/config-check <args>` (or any skill that shares a built-in command prefix) is no longer captured by the shorter built-in handler. Fixes #84572. Thanks @infracore.
- Cron: use structured embedded-run denial metadata for isolated scheduled tasks so blocked exec requests fail the job without treating ordinary assistant prose as a denial. (#84067) Thanks @abnershang.
- Cron: keep recovered tool warnings diagnostic for successful scheduled runs so final cron output is delivered instead of being replaced by a post-processing warning. (#84045) Thanks @abnershang.
- Plugins/perf: thread explicit plugin discovery results through `loadBundledCapabilityRuntimeRegistry`, `resolveBundledPluginSources`, and `listChannelCatalogEntries` so callers that already hold a discovery result skip redundant filesystem walks. Thanks @SebTardif.
- Android/Control UI Talk: split realtime voice transcript turns, queue PCM playback writes, and add opt-in OpenClaw consult routing for Gateway relay when a realtime provider skips `openclaw_agent_consult`. (#84181) Thanks @VACInc.
- Docker: keep the bundled Codex plugin in official release image keep lists so the default OpenAI agent harness remains available after Docker pruning. Fixes #83613. (#83626) Thanks @YuanHanzhong.
- CLI/channels: preserve the first line of `openclaw channels logs` output when the rolling tail window starts exactly on a line boundary, mirroring the already-fixed `readLogSlice` behavior in `src/logging/log-tail.ts`.
- Control UI: treat terminal session status as authoritative over stale active-run flags so completed terminal runs stop showing abort/live UI. (#84057)
- CLI: preserve embedded equals signs in inline root option values instead of truncating after the second separator. (#83995) Thanks @ThiagoCAltoe.
- Matrix/config: accept `messages.queue.byChannel.matrix` queue overrides and keep queue provider schema/type keys aligned for Matrix, Google Chat, and Mattermost. Thanks @bdjben.
- CLI: format `openclaw acp client` failures through the shared error formatter so object-shaped errors stay readable instead of printing `[object Object]`. Fixes #83904. (#84080)
- Agents/message-tool: normalize non-canonical message body aliases (`SendMessage`, `content`, `text`) to `message` before send validation so model-emitted tool calls with aliased body keys are delivered instead of rejected. (#84079)
- Providers/Ollama: default unknown-capabilities models to tool-capable so discovered native Ollama models can use tools when `/api/show` omits capabilities. (#84055) Thanks @dutifulbob.
- Codex app-server: disable native Code Mode, user MCP, and app-backed plugin execution while OpenClaw sandboxing is active, routing shell access through `sandbox_exec`/`sandbox_process` instead. (#84388) Thanks @joshavant.
- Installer/Windows: launch `install.ps1` onboarding as an attached child process so fresh native Windows installs do not freeze visibly at `Starting setup...` or corrupt the wizard's terminal rendering.
- CLI/update: keep restart health checks working across one-version CLI/Gateway protocol skew and use the managed Gateway service Node for all follow-up commands even when the package root is unchanged, so `openclaw update` no longer silently switches the gateway to a different Node binary when multiple Node installations are present. Thanks @amknight.
- CLI/gateway: include the running Gateway version in `gateway status` JSON output, preserving existing server metadata while falling back to status RPC data for read probes. Fixes #56222. Thanks @galiniliev.
- Memory/search: close local embedding providers when active-memory searches time out so pending local model loads and embedding contexts are aborted and released. (#83858) Thanks @brokemac79.
- CLI/nodes: request pending node surface approval scopes before `openclaw nodes approve` so exec-capable node approval can use admin-scoped Gateway credentials instead of failing with `missing scope: operator.admin`. (#84392) Thanks @joshavant.
- Gateway: reject slow node event sends before outbound buffers grow unbounded and log the rejected payload diagnostic. (#84387) Thanks @samzong.
- Agents: include bounded trajectory queued-writer diagnostics in `pi-trajectory-flush` timeout warnings so flush stalls show pending writes, queued bytes, and append state. Fixes #82961. (#82962) Thanks @galiniliev.
- Agents/subagents: recover stale completion announces by retrying unsupported transcript-wait wakes without transcript waiting and forcing a message-tool handoff when the requester run is already stale. Fixes #83699. (#83700) Thanks @galiniliev.
- Providers/Anthropic: route Anthropic model refs selected with Claude CLI auth through the Claude CLI runtime so shorthand refs such as `anthropic/opus-4.7` no longer fall back to embedded Anthropic billing. Fixes #84222. (#84374) Thanks @joshavant.
- Agents: honor explicit `models.providers.<id>.timeoutSeconds` values above the default idle watchdog for cloud and self-hosted providers, so long first-token waits no longer fall back at ~120s when the provider timeout is higher. (#83979) Thanks @yujiawei.
- Agents/Codex: keep encrypted Responses reasoning replay provenance-bound so stale mirrored Codex transcripts drop invalid encrypted content before request assembly while preserving matching same-session replay. Fixes #83836. (#84367) Thanks @joshavant.
- Agents/subagents: skip stale embedded-run wake probes for dormant completion requesters, so late subagent completions go straight to requester-agent/direct handoff instead of producing `reason=no_active_run` queue noise. (#82964) Thanks @galiniliev.
- CLI: retry config snapshot reads after a transient failure so one rejected read no longer poisons later commands in the same process. (#83931) Thanks @honor2030.
- TUI: handle German-layout Kitty keyboard input by ignoring printable release events and accepting AltGr-produced printable characters such as `@` and `€`. Fixes #48897.
- Media: decode URL path basenames before using them as remote media fallback filenames, so files like `My%20Report.pdf` are surfaced as `My Report.pdf`. Fixes #84050. (#84052) Thanks @jbetala7.
- WhatsApp: clarify inbound group diagnostics so observed but unregistered groups point to `channels.whatsapp.groups` without changing routing or sender authorization. (#83846) Thanks @neeravmakwana.
- WhatsApp: drain pending outbound deliveries on a 30s periodic timer in addition to the reconnect handler, so messages enqueued while the provider is already connected no longer wait for the next reconnect to send. (#79083) Thanks @Oviemudiaga.
- CLI/TUI: include gateway plugin slash commands in TUI autocomplete, so connected sessions can suggest plugin-owned commands exposed by the running Gateway. (#83640) Thanks @se7en-agent.
- Gateway/mobile: restore QR setup-code handoff of bounded operator tokens for iOS and Android onboarding while keeping admin and pairing scopes out of bootstrap. (#83684) Thanks @ngutman.
- iOS: repair Release archive compilation for the TestFlight build. (#84255) Thanks @ngutman.
- Agents/compaction: bound plugin-owned CLI transcript compaction with the host safety timeout so a hung context engine can no longer stall post-turn cleanup. (#84083) Thanks @100yenadmin.
- Control UI/usage: truncate long context skill, tool, and file names in the usage panel while keeping the full name available on hover. (#42197) Thanks @Rain120.
- Codex: respect explicit `models auth order set` and `config.auth.order` precedence over stale `lastGood` in `/codex account`, and show `no working credential` when every explicit-order profile is ineligible instead of marking a lower-ranked profile as active. Fixes #84386. (#84412) Thanks @openperf.
- Agents: honor `messages.suppressToolErrors` for mutating tool failures so configured chat surfaces do not receive separate warning payloads. (#81561) Thanks @moeedahmed.
- Agents/fallback: surface billing guidance for mixed rate-limit plus billing fallback exhaustion instead of generic failure copy. Fixes #79396. (#79489) Thanks @aayushprsingh.
## 2026.5.19
### Changes
- Agents: clarify that fixes should default to clean bounded refactors, lean internals, and explicit plugin SDK/API deprecation paths.
- Agents/tools: normalize Swagger/OpenAPI refs and OpenAPI schema annotations when preparing tool parameter schemas.
- Dependencies: update `@openclaw/proxyline` to 0.3.3.
- Dependencies: update Pi packages to 0.75.1 and raise the minimum supported Node.js 22 line to 22.19.
- Docker/Podman: add `OPENCLAW_IMAGE_APT_PACKAGES` as the runtime-neutral image build arg for extra apt packages while keeping `OPENCLAW_DOCKER_APT_PACKAGES` as a legacy fallback. (#62431) Thanks @urtabajev.
- Gateway/ACPX: attribute startup probe, config, runtime, and resource-count costs in restart traces without changing readiness behavior. (#83300) Thanks @samzong.
- Gateway: overlap startup logging and plugin-service startup with channel sidecars to reduce restart ready latency while preserving `/readyz` sidecar gating. (#83301) Thanks @samzong.
- Plugins/admin-http-rpc: allow trusted admin HTTP RPC clients to start and wait for web QR login flows. (#83259) Thanks @liorb-mountapps.
- Mac app: redesign Settings pages with consistent card layouts, cached navigation, cleaner permissions/voice/skills/cron/exec/debug panes, and steadier spacing around the native sidebar.
- Mac app: refine Voice & Talk recognition-language and wake-phrase settings so they use the same compact card rows as the rest of Settings.
- Skills: rename the repo-local Codex closeout review skill and helper to `autoreview` while preserving the Codex-first fallback behavior.
- Skills: add a meme-maker skill for curated template search, local SVG/PNG rendering, Imgflip hosted rendering, and Know Your Meme provenance links.
- Skills CLI: allow `openclaw skills install` and `openclaw skills update` to target shared managed skills with `--global`. (#74466) Thanks @Marvae.
- Browser: surface pending and recently handled modal dialogs in snapshots, return `blockedByDialog` when an action opens a modal, and allow `browser dialog --dialog-id` to answer pending dialogs.
- Browser CLI: add `openclaw browser evaluate --timeout-ms` so long-running page functions can extend both the evaluate action and request timeout budgets. (#83447) Thanks @eefreenyc.
- Codex app-server: scope OpenClaw prompt guidance by runtime surface so native Codex keeps Codex-owned base/personality instructions while OpenClaw contributes only runtime context, delivery guidance, and explicitly scoped command hints. (#83454) Thanks @100yenadmin.
- Docker/Podman: add `OPENCLAW_IMAGE_PIP_PACKAGES` for opt-in Python package installation in local image builds. (#83771) Thanks @stephenredmond-straiteis.
- Agents/tools: shorten built-in tool descriptions and schema hints across media, messaging, sessions, cron, Gateway, web, image/PDF, TTS, nodes, and plan tools while preserving routing guardrails.
- CLI/plugins: add `defineToolPlugin` plus `openclaw plugins build`, `validate`, and `init` for typed simple tool plugins with generated manifest metadata, optional tool declarations, and context factories.
- Agents/skills: tighten bundled skill prompts and metadata, quote skill descriptions, refresh current CLI/API guidance, and update embedded sherpa-onnx runtime downloads.
- Skills: update the Obsidian skill to target the official `obsidian` CLI and require its registered binary instead of the third-party `obsidian-cli`.
- Skills: add a Python debugging skill for pdb, breakpoint(), post-mortem inspection, and debugpy remote attach.
- Codex: add `/codex plugins list`, `enable`, and `disable` for managing configured native Codex plugins from chat without editing config by hand.
- Plugins/messages: add presentation capability limits for channel renderers, adapt rich message controls before native rendering, and mark legacy `interactive`/Slack directive producer APIs as deprecated.
- Plugins/subagents: store channel delivery routes as canonical session metadata and deprecate ad hoc subagent hook delivery-origin fields in favor of core route projection.
- Proxy: support HTTPS managed forward-proxy endpoints and scoped `proxy.tls.caFile` CA trust for proxy endpoint TLS. (#79171) Thanks @jesse-merhi.
- QA-Lab: add first-hour 20-turn and optional 100-turn runtime parity scenarios, with tier metadata for standard and soak QA gates. Fixes #80338; refs #80337. Thanks @100yenadmin.
- QA-Lab: add `openclaw qa suite --runtime-parity-tier` and wire the standard Codex-vs-Pi tier into release checks separately from optional/live-only/soak lanes. Fixes #80337. Thanks @100yenadmin.
- QA-Lab: add runtime tool fixture scenarios and coverage reporting for Codex-native workspace tools, OpenClaw dynamic tools, and optional plugin-backed tools. Fixes #80173. Thanks @100yenadmin.
- QA-Lab: expose runtime tool fixture coverage through `openclaw qa coverage --tools`, with optional suite-summary evaluation for parity gate artifacts. Thanks @100yenadmin.
- QA-Lab: schedule a live-frontier Codex-vs-Pi runtime token-efficiency artifact lane in the all-lanes QA workflow. Fixes #80175. Thanks @100yenadmin.
- QA-Lab: hard-gate required OpenClaw dynamic runtime-tool drift in the standard Codex-vs-Pi tier with a blocking release-check verifier and publish the tool coverage report artifact. Fixes #80339; refs #80319. Thanks @100yenadmin.
- QA-Lab: add the personal-agent approval-denial scenario so the benchmark pack verifies denied local reads stop cleanly without tool progress or fixture leaks. (#83150) Thanks @iFiras-Max1.
- QA-Lab: extend the personal-agent benchmark pack with a local task followthrough scenario for proof-backed pending, blocked, and done status reporting. Thanks @iFiras-Max1.
- QA-Lab: add a report-only dreaming shadow-trial scenario so candidate memory promotion can be evaluated without mutating `MEMORY.md`. Thanks @iFiras-Max1.
- Gateway/performance: add `pnpm test:restart:gateway` benchmark tooling for repeated restart readiness, downtime, trace, and resource-slope evidence. (#83299) Thanks @samzong.
- Android: switch Talk Mode to realtime Gateway relay voice sessions with streaming mic input, realtime audio playback, tool-result bridging, and on-screen transcripts. (#83130) Thanks @sliekens.
- Gateway/config: expose config lookup reload metadata so tools can distinguish restart-required, hot-reloadable, and no-op fields before applying config edits. Fixes #81409. (#81612) Thanks @LLagoon3.
- Telegram: add allowlisted native DM draft previews for transient tool progress while keeping final answers on the normal persistent delivery path. (#83622) Thanks @akrimm702.
- QA-Lab: add a personal-agent share-safe diagnostics artifact scenario so support handoffs keep useful status while omitting raw personal content. Thanks @iFiras-Max1.
- QA-Lab: add a personal-agent no-fake-progress scenario so completion claims stay tied to local evidence instead of unsupported external progress. (#83824) Thanks @iFiras-Max1.
### Fixes
- Agents/exec approvals: return approved WebChat gateway exec output inline after native approval instead of leaving the model waiting for an async follow-up. (#82019) Thanks @Zac-W.
- CLI/node: reject invalid explicit `node run --port` values instead of silently falling back to the configured or default port. Fixes #83923. Thanks @davinci282828.
- CLI: reject explicit port numbers above 65535 before they reach Gateway or Node bind paths. Fixes #83900. (#84008) Thanks @hclsys.
- Codex app-server: preserve plugin tool auth profiles when Codex owns model transport so OpenClaw dynamic tools can resolve their provider credentials. (#83603) Thanks @rubencu.
- Memory/search: scan the JS-side fallback vector path (used when the sqlite-vec index is unavailable or has a mismatched dimension) in bounded rowid batches and yield to the event loop between batches so large chunk tables can no longer pin the Node.js main thread for multi-second windows. Also keeps the SQL prepared statement rooted in a local so node:sqlite cannot finalize it mid-scan under heap pressure. Fixes #81172. Thanks @dev23xyz-oss.
- Backup: dereference hardlinks during archive creation and reject unsafe hardlink targets during verification so archives that pass `backup verify` do not fail broad extraction on macOS tar. Fixes #54242. Thanks @jason-allen-oneal.
- Memory Wiki: preserve fs-safe diagnostics when bridge source page writes fail for non-symlink filesystem safety reasons, so directory collisions are reported with the underlying error code. (#83776) Thanks @TurboTheTurtle.
- Telegram: keep forum topics from blocking sibling topic traffic by routing inbound serialization, media/text buffers, and account API queues on topic-aware lanes. (#83829)
- Telegram: keep queued forum-topic follow-up messages from inheriting superseded source abort signals, so later same-topic user turns can still run and reply after an active turn is replaced. (#83827) Thanks @VACInc.
- CLI/update: bypass npm freshness filters consistently during managed package and plugin installs so freshly published release plugins remain installable. Thanks @jalehman.
- CLI/update: guide root-owned npm install EACCES recovery by stopping the managed Gateway before manual package replacement, then reinstalling and restarting the service. Fixes #83747. (#83757) Thanks @brokemac79.
- Agents/subagents: keep collect-mode announce queues batching unresolved-origin items with compatible same-route messages and resume collection after a true cross-channel drain when a later compatible batch remains. Fixes #83577.
- CLI/config: preserve numeric-looking record keys such as Discord guild IDs when creating missing config containers with `config set`. (#83769) Thanks @TurboTheTurtle.
- Skills: refresh existing session skill snapshots when watched skill roots change, so changed extra skill directories take effect without starting a new session. Fixes #83782. (#83800) Thanks @hclsys.
- Providers/Anthropic: preserve native image input for current Claude model rows when stale local catalog data marks them text-only. (#83756) Thanks @TurboTheTurtle.
- Providers/Anthropic: preserve Claude 4 image capability when configured model refs resolve through a stale local catalog row. (#83756) Thanks @TurboTheTurtle.
- Providers/DeepSeek: normalize MCP tool schemas with `anyOf`/`oneOf` unions before normal and compaction requests reach DeepSeek, preventing union-shaped parameters from being rejected. (#83766) Thanks @TurboTheTurtle.
- Control UI: render live tool progress from session-scoped `session.tool` Gateway events so externally started runs show their tool cards in the active session. (#83734) Thanks @TurboTheTurtle.
- Outbound: resolve send-capable channel plugins from the active runtime registry when the pinned startup registry only has setup metadata. (#83733) Thanks @TurboTheTurtle.
- Discord: preserve streamed reply previews when recovered tool-warning finals are delivered before or after the assistant's final reply. (#84169) Thanks @neeravmakwana.
- Control UI: keep the chat delete confirmation popover clamped inside the visible viewport on small screens. (#83804) Thanks @ThiagoCAltoe.
- Browser: enforce current-tab URL allowlist checks for `/act` evaluate/batch actions and `/highlight` routes while leaving tab-management actions unblocked. (#78523)
- CI: require real-behavior-proof verdict markers to come from the ClawSweeper GitHub App before accepting exact-head proof. (#83692)
- Models: show the effective OpenAI/Codex auth profile in `/models` provider headers instead of falling back to the OpenAI env-key label. (#83697) Thanks @yu-xin-c.
- CLI: include active bundled loopback MCP tools in CLI system prompts and reset provider-side CLI sessions when that prompt-visible tool surface changes. (#83785) Thanks @TurboTheTurtle.
- Browser: keep a profile `cdpPort` when its `cdpUrl` omits a port, while still letting explicitly written URL ports win. (#82166) Thanks @Marvae.
- Agents/image generation: allow distinct `image_generate` prompts to start separate session-backed background tasks while same-prompt retries still return the active task status. (#83614) Thanks @Elarwei001.
- Gateway/WebChat: honor configured `channels.webchat.textChunkLimit` and `chunkMode` overrides when chunking WebChat replies. (#83713)
- Control UI: stop the chat reading indicator from sticking after an assistant response finishes. (#83515) Thanks @njuboy11.
- Skills: reject empty or whitespace-only skill names and descriptions during quick validation. (#27061)
- Sessions: skip trailing custom transcript entries when checking tail assistant replies so embedded CLI gap-fill does not duplicate canonical assistant output. (#83635) Thanks @yaoyi1222.
- Memory Wiki: keep `wiki_lint` tool output path-safe by reporting vault-internal lint reports as relative paths in tool text and details while preserving absolute report paths for CLI/file callers. (#83439) Thanks @LLagoon3.
- Telegram: keep verbose tool progress visible without mirroring non-final progress into active session transcripts, preventing embedded provider replies from aborting mid-run. (#83631) Thanks @kurplunkin.
- Telegram: log successful outbound text and media deliveries with account, chat, message, operation, thread, reply, silent, and chunk metadata while keeping message bodies out of logs. Fixes #83196. (#83247) Thanks @jrwrest.
- Cron: link isolated scheduled task runs to their stable cron session so task status and cleanup can follow the backing agent run. (#83606) Thanks @jai.
- Codex app-server: mark Codex-native subagent task mirrors terminal when blocked or failed spawn-agent calls arrive with stale initializing child state, preventing task registry entries from staying running. Fixes #83852. (#83945) Thanks @joshavant.
- CLI: enforce the documented Node.js 22.19 runtime floor in the source launcher.
- Release stability: repair broad-gate regressions in requester-agent completion handoff, QA-Lab mock spawn attribution, Slack monitor test isolation, plugin uninstall peer fixtures, and Node-floor launcher contract coverage.
- Agents/replies: persist queued follow-up user messages and assistant error stubs only once across model-fallback retries, preventing repeated provider rejections from corrupted same-role session transcripts. Fixes #83404. (#83417) Thanks @yetval.
- Telegram: preserve reply-target context for bare mention replies on runtime-only turns so the model sees the replied-to message body. Fixes #83767. (#83953) Thanks @joshavant.
- ClawHub: preserve configured base URL path prefixes when building API request URLs, so self-hosted ClawHub instances mounted under a subpath keep routing correctly. (#83982) Thanks @ThiagoCAltoe.
- Slack: persist delivered inbound message IDs and fail closed when same-channel thread replies lose their thread context, preventing delayed duplicate replies and accidental channel-root posts. Fixes #83521. Thanks @shannon0430.
- Codex app-server: complete OpenClaw dynamic tool diagnostics at the request boundary so successful, failed, timed out, aborted, and blocked tool calls do not leave active tool state behind. Fixes #83474. Thanks @rozmiarD.
- Doctor/Codex: warn when Linux host policy blocks the Codex bwrap user or network namespace path used by sandboxed app-server turns, with Ubuntu/AppArmor repair guidance. Refs #83018.
- Gateway/config: keep config writes from failing on unrelated unresolved auth-profile SecretRefs while preserving live auth-profile runtime snapshots.
- Gateway/sessions: clear stored CLI provider resume bindings on non-subagent `/reset` so the next turn starts a fresh provider-side CLI conversation instead of resuming old context. (#83448) Thanks @jasonyliu.
- Doctor: preserve legacy whole-agent Claude CLI intent by moving matching Anthropic model selections to model-scoped runtime policy before removing stale runtime pins. Fixes #83491. Thanks @danielcrick.
- Discord/OpenAI: keep realtime Discord voice sessions hearing follow-up turns with OpenAI realtime and prebuffer assistant playback to avoid choppy starts. (#80505) Thanks @Solvely-Colin.
- LM Studio: resolve env-template API keys like `${LMSTUDIO_API_KEY}` through the standard SecretInput path instead of sending the raw template as the bearer token, and preserve header-auth and discovery-key precedence when the template is unset. Fixes #80495. (#80568) Thanks @MonkeyLeeT.
- Discord/subagents: route the initial reply from thread-bound delegated sessions into the bound Discord thread instead of the parent channel. Fixes #83170. (#83172) Thanks @100menotu001.
- Gateway/sessions: rotate failed agent sessions when their transcript file is missing instead of wedging per-channel lanes. Fixes #83488. (#83553) Thanks @LLagoon3.
- Agents: refresh final-delivery routing from fresh session state before declaring a no-send failure, keeping recovered runs on the normal durable delivery path. (#83835) Thanks @joshavant.
- Agents: guard final-delivery fresh session routing against mismatched logical sessions before reusing recovered delivery context. (#83928) Thanks @joshavant.
- Media: prevent image metadata probing from invoking external decoder delegates on unrecognized image bytes, and stop fallback chaining after real processing errors.
- Media: install Sharp with the root package and fall back to sips, Windows native imaging, ImageMagick, GraphicsMagick, or ffmpeg for image resizing/conversion when Sharp is unavailable. Fixes #83401. Thanks @scotthuang.
- Channels/bundled: append `openclaw doctor --fix` guidance to the bundled-channel load warnings emitted on `ERR_MODULE_NOT_FOUND` / `MODULE_NOT_FOUND` (including those wrapped on `.cause` by the native-require loader), so users hitting unstaged plugin runtime deps (e.g. `nostr-tools`) see an actionable repair hint instead of a bare module-not-found warning. (#76974) Thanks @BSG2000.
- Telegram: deliver generated media completions back into forum topics by preserving topic IDs across requester-agent handoff. (#83556) Thanks @fuller-stack-dev.
- Gateway: defer update-check startup until after readiness so package update checks no longer block sidecar-ready startup, while preserving update broadcasts and shutdown cleanup. (#83520) Thanks @samzong.
- Telegram: keep `/btw` and read-only status commands from aborting active runs, and avoid retaining raw update payloads in timed-out spool tombstones. Refs #83272.
- Agents: log strict-agentic execution contract diagnostics only when the planning-only retry path actually triggers.
- Agents: stop embedded session takeover and session write-lock errors from consuming model fallbacks while preserving provider fallback metadata. Fixes #83510. Thanks @luyao618.
- Agents/video: hide `video_generate` reference-audio parameters unless a registered video provider supports audio inputs.
- Plugins: fall back to npm for official ClawHub updates when artifact downloads are unavailable, including beta-to-default fallback and dry-run version reporting.
- Plugins/xAI: echo PKCE challenge fields during OAuth authorization-code token exchange for xAI token-endpoint compatibility. (#83499) Thanks @fuller-stack-dev.
- Codex app-server: hydrate current inbound image attachments before queued runs so Responses-backed agents receive Discord and other channel images as native vision input. Fixes #83466. Thanks @iannwu.
- Codex app-server: keep native code mode available without forcing code-mode-only so OpenClaw dynamic tool turns complete through the app-server tool bridge. Fixes #83109. Thanks @daswass.
- Codex app-server: expose OpenClaw's sandbox-routed shell as `sandbox_exec`/`sandbox_process` for non-Docker sandbox backends so SSH sandbox agents keep a correctly routed shell path without shadowing Codex native shell. Fixes #80322. Thanks @keramblock.
- Release stability: recover stale session diagnostics and Codex OAuth fallback state so stuck runs and reused refresh tokens clear without blocking follow-up work. (#83503) Thanks @100yenadmin.
- Messages/TTS: apply TTS directives before message-tool sends reach core, gateway, or plugin delivery so opt-in message-tool rooms and proactive sends attach voice notes instead of leaking raw tags. Fixes #81598. Thanks @CG-Intelligence-Agent-Jack and @CoronovirusG10.
- Messages/Codex: keep Codex direct/source chats on message-tool visible delivery by default while documenting and testing `messages.visibleReplies: "automatic"` as the old-mode opt-out; channel wildcard model overrides now apply to direct chats before harness delivery defaults.
- Memory/QMD: keep archived session transcript hits visible after QMD export while preserving normal `.md` session ids that only resemble archive names. (#83518; fixes #83506) Thanks @tanshanshan.
- Codex app-server: preserve network access for sandboxed Codex code-mode turns when the OpenClaw sandbox allows outbound egress. Fixes #83347. Thanks @YusukeIt0.
- Codex app-server: honor writable Docker bind mounts for sandboxed workspace-write turns while disabling native Code Mode when container-path aliases or read-only bind shadows cannot be represented safely host-side. Fixes #83737. (#83849) Thanks @joshavant.
- QA-Lab: keep the OTLP smoke decoder independent of removed OpenTelemetry generated-root internals.
- Messages: default group/channel visible replies to automatic final delivery again, keeping `message_tool` opt-in for ambient/shared rooms and tool-reliable models.
- CLI/TUI: force standalone `/exit` runs to terminate after `runTui` returns so onboarding-launched TUI children do not stay alive invisibly. (#83501) Thanks @fuller-stack-dev.
- Agents/code mode: honor per-agent code-mode config in schema, runtime catalog activation, and model payload filtering. Fixes #83388. Thanks @Kaspre.
- Agents/code mode: preserve agent, session, run, and channel context in `before_tool_call` hooks for top-level `exec`/`wait` dispatches. Fixes #83387.
- QQBot: shorten C2C typing indicators to a 10-second window renewed every 5 seconds, capped to keep a final passive-reply slot available. (#83469)
- Replies: keep final payload delivery after live preview updates so channels can finalize or send the completed answer instead of losing preview-only drafts. (#83468)
- Discord: deliver final replies in progress-mode preview streams instead of deduplicating the final visible message. (#83443) Thanks @compoodment.
- Providers/Xiaomi: replay MiMo Anthropic-compatible `reasoning_content` as provider-required thinking blocks even when OpenClaw thinking is disabled, fixing follow-up tool turns for `mimo-v2-flash`. Fixes #83407. Thanks @Xgenious7.
- Agents/exec approvals: forward approval-runtime credentials on agent-owned Gateway approval calls so approved async commands complete through the existing runtime path instead of stalling on unauthenticated follow-up calls. Thanks @IWhatsskill, @Patrick-Erichsen, and @jesse-merhi.
- Gateway/skills: preflight remote macOS skill-bin refreshes with a WebSocket connectivity check so stale node sessions skip quickly instead of logging slow `system.which` timeout warnings.
- CLI/config: keep broken discovered plugins that are not referenced by active config from failing `openclaw config validate`, while preserving fatal errors for explicitly configured plugin entries.
- GitHub Copilot: drop unsafe native Responses reasoning replay items with non-replayable IDs before dispatch, preventing affected Copilot sessions from failing with `invalid_request_body`. Fixes #83220. Thanks @galiniliev.
- Agents/Codex: fail closed when an explicitly requested Codex harness is not registered instead of silently trying configured model fallbacks. Fixes #83349. Thanks @r2-vibes.
- QA-Lab: make runtime tool coverage fail on missing required tool exercise instead of treating pass/pass parity envelope drift as missing coverage.
- Core/plugins: harden clawpatch-reported edge cases across gateway auth cleanup, Claude session id paths, plugin activation policy, apply-patch hunk handling, diagnostic redaction, and plugin metadata validation.
- UI: show reasoning choices as plain labels instead of leaking internal override wording in session and chat pickers.
- Mac app: avoid repeating the Configuration heading inside channel quick settings.
- Mac app: keep the Settings sidebar always visible and remove the redundant titlebar hide/show control.
- Mac app: normalize Settings pane content margins so pages share the same left and right rail.
- Mac app: prefer explicit private/Tailscale/LAN Gateway endpoints over SSH tunnels, preserve legacy loopback tunnel configs, persist transport choices, and show captured SSH stderr when tunneling really fails.
- Gateway/sessions: keep ACP/acpx and runtime child sessions visible in configured-only session lists when their owner or parent session belongs to a configured agent.
- Mac app: keep app-level menu commands and Dashboard failure states reachable when the remote Gateway is disconnected.
- Mac app: allow longer Gateway and Context errors to wrap in the menu instead of truncating the useful failure detail.
- Mac app: tighten remote Gateway fields in Settings so the Connection pane keeps readable labels and full action button text.
- Mac app: keep custom Settings card rows left-aligned and full-width so Discovery and status sections no longer appear centered or detached.
- Mac app: align Location permission controls to the same trailing column as the rest of Settings.
- Mac app: add Dashboard, Chat, Canvas, and Settings shortcuts to the Dock icon menu.
- Mac app: replace the Settings window's native split-view sidebar with an explicit layout so page content keeps its leading gutter when the sidebar is shown or hidden.
- Mac app: render channel quick config as aligned Settings rows and hide schema-only variants that cannot be edited safely from the quick pane.
- Gateway/webchat: hide internal runtime-context and other `display: false` transcript messages from Chat history and live message events. Fixes #83216. Thanks @EmpireCreator.
- CLI/help: keep `gateway`, `doctor`, `status`, and `health` help registration out of action/runtime imports so subcommand `--help` stays lightweight in constrained terminals. Fixes #83228. Thanks @dfguerrerom.
- CLI/help: show plugin-owned command help based on the active memory slot so LanceDB memory users see `ltm` instead of unavailable `memory` commands. Fixes #83745. (#83841) Thanks @joshavant.
- Cron/Discord: keep explicit announce runs in message-tool-only source-reply mode so scheduled agent turns post once instead of also echoing through automatic visible replies. Fixes #83261. Thanks @Theralley.
- Telegram: preserve forum-topic origin targets in inbound, audio-preflight, and skipped-message hook contexts so follow-up delivery stays bound to the originating topic. Fixes #83302. Thanks @M00zyx.
- Telegram: retry HTTP 421 Misdirected Request send failures on a fresh fallback transport so transient edge-node routing errors no longer drop outbound replies. Fixes #48892. (#48908) Thanks @MarsDoge.
- Telegram: fail topic sends closed when Telegram reports `message thread not found` instead of retrying without `message_thread_id` into the base chat. Refs #83302.
- Config/subagents: remove ignored agent-model `timeoutMs` keys, keep subagent model config to primary/fallback selection, and clean shipped stale config through doctor. Fixes #83291. Thanks @giodl73-repo.
- Mac app: align the Sessions settings pane with the standard Settings page gutter and row spacing.
- OpenAI/Codex: stop rejecting available `openai-codex` GPT-5.1, GPT-5.2, and GPT-5.3 model refs during config validation, while keeping removed Spark aliases suppressed. Fixes #83303.
- Plugins/xAI: complete OAuth-backed xAI login and sidecar auth fixes, including guarded loopback callback CORS handling, video generation polling/defaults, and native-host User-Agent attribution. (#83322) Thanks @Jaaneek.
- Codex app-server: preserve streamed native command output in mirrored transcripts and trajectory exports when final snapshots omit aggregated output. (#83200) Thanks @rozmiarD.
- Codex app-server: fail closed when chat or sender policy denies tools, disabling native code, app, environment, and user MCP surfaces for restricted turns. (#82374) Thanks @VACInc.
- Codex app-server: keep recent context-engine messages when oversized projected history is truncated, so short follow-ups in long channel sessions do not fall back to stale earlier turns. (#83127) Thanks @VACInc.
- Codex app-server: keep OpenClaw session spawning searchable while steering Codex-native delegation through native subagents, avoiding duplicate direct subagent surfaces. (#83329) Thanks @fuller-stack-dev.
- Codex app-server: recover stale childless Codex-native subagent task mirrors during maintenance and allow their registry rows to be cancelled without an OpenClaw child session. (#82836) Thanks @yshimadahrs-ship-it and @joshavant.
- Feishu: return bound subagent delivery origins from session thread setup so Feishu subagent completions route back to the same DM or topic. (#83190) Thanks @100menotu001.
- CLI/update: tailor post-update Gateway recovery hints by platform, showing systemd, LaunchAgent, Scheduled Task, or generic service-manager guidance instead of macOS-only recovery text. (#83096) Thanks @rubencu.
- Plugins: apply a default 15-second timeout to legacy `before_agent_start` hooks so hung plugin handlers no longer block agent startup. Fixes #48534. (#83136) Thanks @therahul-yo.
- Feishu: refresh inbound session delivery context for DM, group, and broadcast turns so later replies do not inherit stale WebChat routing. Fixes #78274.
- Agents/subagents: require the initial subagent registry save before reporting spawn accepted, returning a spawn error instead of losing an untracked run when the registry write fails. (#83146) Thanks @yetval.
- QA-Lab/qa-channel: attach redacted agent tool-start traces to outbound `QaBusMessage` records so scenarios can assert actual tool use instead of relying only on reply text. Fixes #67637. Thanks @100yenadmin.
- QA-Lab: fail live runtime parity reports when assistant-message usage is missing, preventing `0 vs 0` live token rows from being reported as passing proof. Fixes #80411. Thanks @100yenadmin.
- QA-Lab: add a runtime token-efficiency sidecar report that classifies Codex savings separately from regressions and fails only positive Codex-over-Pi live token deltas above threshold. Fixes #81093. Thanks @100yenadmin.
- QA-Lab: fail Codex-backed OpenAI live runtime-pair runs before launching isolated workers when no portable Codex auth is available, while staging API-key fallbacks and configured Codex keys for isolated QA agents. Fixes #80412. Thanks @100yenadmin.
- QA-Lab: refresh parity gates, mock frontier fixtures, model scenarios, and workflow artifact lanes to compare GPT-5.5 against Claude Opus 4.7. Fixes #74262. Thanks @100yenadmin.
- QA-Lab: make mock parity dispatch provider-aware for source discovery and subagent scenarios so OpenAI and Anthropic lanes no longer share identical canned plans. Fixes #64879. Thanks @100yenadmin.
- QA-Lab: stop returning Control UI bearer tokens from unauthenticated bootstrap payloads and bind Docker harness ports to loopback-only host addresses. (#66355) Thanks @pgondhi987.
- Mac app: avoid a SwiftUI metadata crash when rendering the Cron Jobs settings pane.
- Agents/subagents: preserve run-mode keep subagent registry entries past the session sweep TTL, so kept subagent runs remain visible after cleanup completes. Fixes #83132. (#83168) Thanks @yetval.
- Agents/OpenAI streams: yield via `setTimeout(0)` instead of `setImmediate` between bursty Responses chunks so abort timers can fire during the yield, keeping cancel-on-timeout responsive on hot streams. Refs #82462.
- Agents/Codex: keep legacy `oauthRef`-backed OAuth profiles usable while `openclaw doctor --fix` migrates them back to inline credentials, without creating new sidecar credentials. (#83312) Thanks @joshavant.
- Agents/Codex: load the selected provider owner alongside the Codex harness runtime so `openai-codex` models resolve when plugin allowlists scope runtime loading. Fixes #83380. (#83519) Thanks @joshavant.
- Telegram: fail stalled isolated-ingress handlers into tombstones and abort same-lane reply work before restarting, so later same-chat updates drain after a hung turn. Fixes #83272. (#83505) Thanks @joshavant.
- CLI/config: send SecretRef diagnostics to stderr so JSON command stdout remains parseable.
- CLI/doctor: seed Control UI allowed origins when migrating legacy non-loopback gateway bind host aliases like `0.0.0.0`. Fixes #83286. Thanks @giodl73-repo.
- CLI/plugins: ship the bundled memory CLI as a package entry so package-installed `openclaw memory` commands register correctly.
- CLI/update: defer doctor-time plugin package installs during package swaps and seed post-core repair from the updated install registry, preventing duplicate reinstall failures.
- CLI/update: preserve old-parent-readable config metadata during legacy package handoffs, fall back only to official `@openclaw/*` npm plugin packages when ClawHub plugin artifacts are unavailable, and keep managed service package roots authoritative during updates.
- Feishu: detect SecretRef top-level credentials as a configured default account instead of treating object-backed app secrets as missing.
- Gateway/restart: keep ordinary unmanaged SIGUSR1/config restarts in-process instead of detach-spawning an orphaned child, preserving custom supervisor PID tracking while leaving update restarts on the fresh-process path. Fixes #65668.
- CLI/completion: resolve concrete PowerShell profile paths and reload commands during setup and doctor completion installation. Fixes #44296. (#83059) Thanks @yu-xin-c.
- Telegram: keep isolated long polling below the hard `getUpdates` request guard so idle bot accounts with high `timeoutSeconds` do not false-disconnect and restart-loop. Fixes #83264. Thanks @riccodecarvalho.
- Providers/Google: preserve and recover Gemini 3 tool-call thought signatures during native replay so function-calling turns no longer fail with missing `thought_signature` 400s. Fixes #72879. (#80358) Thanks @abnershang.
- Telegram: skip transcript-only delivery mirrors and gateway-injected rows when resolving latest assistant text, preventing retained previews from replacing final replies with stale fragments. Fixes #83159. (#83362) Thanks @joshavant.
- Memory/QMD: keep lexical search on raw hyphenated queries while normalizing semantic QMD sub-searches, avoiding fallback to the builtin index for dashed identifiers and dates. Fixes #81328.
- Memory-core: distinguish sqlite-vec load failures from missing semantic vector embeddings in degraded `memory index` warnings, so vector recall diagnostics point at unresolved dimensions instead of blaming sqlite-vec when the store is ready. Fixes #75624. (#83056) Thanks @xuruiray and @Noah3521.
- Agents/subagents: preserve sandbox-peer controller ownership while routing completion announcements back to the originating run session, keeping subagent control and completion delivery scoped correctly. Fixes #80201. (#80242) Thanks @Jerry-Xin.
- Gateway: continue restarting remaining channels when one hot-reload channel restart fails, while still reporting aggregate reload failure and rolling back plugin pre-replace stops. Fixes #83054. Thanks @zqchris.
- Gateway/plugins: bind admin HTTP RPC dispatch to the accepting gateway instance so multi-gateway processes cannot execute plugin HTTP control-plane calls against another live gateway. Fixes #83486. (#83487) Thanks @coygeek.
- Telegram: keep hot-reload restarts from marking polling accounts manually stopped and restart isolated ingress cleanly after worker shutdown, preserving Telegram replies across config reloads. Fixes #83008. (#83410) Thanks @joshavant.
- Telegram/Ollama: pass current Telegram image attachments into native PI/Ollama vision turns so live photo prompts reach Ollama as native images. Fixes #83023. (#83516) Thanks @joshavant.
- Gateway/secrets: split the lightweight secrets runtime state and auth-store cache from the full secrets runtime and take a startup fast path when the gateway startup config has no SecretRef values, speeding up secrets startup while preserving cleanup and refresh semantics.
- Codex app-server: rotate oversized native Codex threads before resume and cap dynamic tool-result text entering native Codex sessions, preventing stale oversized context from surviving OpenClaw compaction. (#82981) Thanks @hansolo949.
- Gateway/restart: drain pending replies and active chat runs during restart shutdown before sockets and channels close, aborting timed-out chat runs through the normal cleanup path. (#69121) Thanks @alexlomt.
@@ -58,6 +733,7 @@ Docs: https://docs.openclaw.ai
- Agents/OpenAI: stop post-processing GPT-5 final replies with hardcoded brevity caps, preserving full channel responses instead of appending synthetic ellipses, and log when strict-agentic GPT-5 execution activates. Fixes #82910.
- Mac app: refine the Settings General and Connection panes with cleaner status panels, card rows, and a single native titlebar sidebar toggle.
- Agents/media: deliver failed async image, music, and video generation completions directly when requester-session completion handoff fails, so channel users see provider errors instead of silent fallback stalls.
- Browser/CDP: keep loopback proxy bypass active across both `NO_PROXY` casings and redact home-relative Chrome MCP profile paths in attach-failure diagnostics.
- Agents/music: steer song, jingle, beat, anthem, and instrumental requests toward `music_generate` audio creation instead of lyric-only replies, and reserve `lyrics` for exact sung words.
- Codex app-server: record native Codex tool calls and results into trajectory artifacts so debug/trajectory exports capture the full Codex-native tool history, not just OpenClaw-bridged turns. Thanks @vyctorbrzezowski.
- Codex/app-server: keep bound conversation sessions on the owning agent runtime so native Codex control and follow-up turns do not fall back to the default agent client. Fixes #82954. (#82993)
- Agents/OpenAI: preserve deterministic tool payload ordering for prompt-cache reuse across OpenAI Responses and chat completions calls. (#82940) Thanks @galiniliev.
- ACP/Codex: honor terminal ACP turn results so failed Codex/acpx runs are not recorded as successful after only progress text. Fixes #79522. Thanks @dudaefj.
- Telegram: warn when a media group drops photos that fail to download, including albums where every photo is skipped. Fixes #55216. (#82987) Thanks @eldar702.
- Agents/diagnostics: treat repeated same-handle embedded-run cleanup as idempotent while preserving true replacement-handle mismatch diagnostics. Fixes #82959. (#82960) Thanks @galiniliev.
- Agents/subagents: preserve high-priority `AGENTS.md` policy in bootstrap context when oversized files are trimmed, and warn agents to read the full policy file before relying on scoped rules. Fixes #82920. (#82921) Thanks @galiniliev.
- Agents/skills: apply the full effective tool policy pipeline to inline `command-dispatch: tool` skill dispatch before owner-only filtering, preserving configured allow, deny, sandbox, sender, group, and subagent restrictions. (#78525)
- Codex: avoid spawning native hook relay subprocesses for post-tool/finalize events with no registered hook handlers while preserving pre-tool safety and approval relays. Fixes #76552. (#78004) Thanks @evgyur.
- Channel accounts: keep top-level default channel accounts visible when named accounts are added alongside default credential material, so mixed legacy/new account configs keep resolving `default` instead of silently dropping it.
- Agents/CLI: reject empty successful CLI subprocess replies as `empty_response` and keep them out of shared auth-profile health, so blank Claude CLI results no longer become green no-payload turns. Fixes #83231. (#83421) Thanks @joshavant.
- Codex/Telegram: synthesize native Codex tool progress from final turn snapshots so Telegram `/verbose` stays visible when command events arrive only at completion.
- Codex/Telegram: deliver Codex verbose tool summaries in direct message-tool-only turns while suppressing message-send and activity-log noise. (#83186) Thanks @kurplunkin.
- Mac app: make Channels settings open faster by deferring config-schema work, avoiding startup channel probes, caching decoded channel status rows, and showing only compact quick settings instead of the full generated channel schema.
- Control UI: include the Control UI and Gateway protocol versions in protocol-mismatch errors so stale app/dashboard pairings identify which side needs rebuilding or restarting.
- Gateway/protocol: restore Gateway WS protocol v4 and keep `message.action` room-event metadata on the existing `inboundTurnKind` wire field while preserving internal inbound-event classification.
@@ -87,6 +767,7 @@ Docs: https://docs.openclaw.ai
- Mac app: make Config settings open from shallow schema lookups and load selected paths on demand instead of fetching and rendering the full generated config schema up front.
- Codex: sanitize inline image payloads before Codex app-server and OpenAI Responses replay, and clear poisoned Codex thread bindings after invalid image errors. Fixes #82878.
- Providers/GitHub Copilot: request identity-encoded Copilot API responses across token exchange, catalog, model calls, usage, and embeddings so compressed Business-account error payloads no longer reach JSON parsers as gzip bytes. Fixes #82871. Thanks @tonyfe01.
- Telegram: redact nested raw-update identifiers and user metadata before verbose raw update logging, preserving useful update/message ids without exposing chat, user, command, or profile details. (#82945) Thanks @galiniliev and @joshavant.
- Telegram: preserve replied-to bot messages, captions, and media metadata in group reply chains so follow-up replies understand what the user is reacting to. (#82863)
- Providers/Together: update PI runtime packages to 0.74.1 and emit Together-style `reasoning.enabled`/`max_tokens` controls for reasoning-capable OpenAI-completions models.
- Agents/diagnostics: split slow embedded-run `attempt-dispatch` startup summaries into workspace, prompt, runtime-plan, and final dispatch subspans so traces identify the delayed setup phase. Fixes #82782. (#82783) Thanks @galiniliev.
- Signal: preserve mixed-case group IDs through routing and session persistence so group auto-replies keep delivering after updates. Fixes #82827.
- Agents/tools: keep the `message` tool available in embedded runs when it is explicitly allowed through `tools.alsoAllow` or runtime tool allowlists, so channel plugins with custom reply delivery can still use configured message sends. Fixes #82833. Thanks @cn1313113.
- WhatsApp: honor forced document delivery for outbound image, GIF, and video media so `forceDocument`/`asDocument` sends preserve original media bytes instead of using compressed media payloads. (#79272) Thanks @itsuzef.
- WhatsApp: reject symlinked Web credential files across auth checks and socket startup so unsafe `creds.json` paths cannot be read through. Thanks @mcaxtr.
- WhatsApp: name outbound document attachments from their MIME type when no filename is provided, so PDF and CSV sends arrive as `file.pdf` and `file.csv` instead of an extensionless `file`. Thanks @mcaxtr.
- Process/diagnostics: report active lane blockers in lane wait warnings so `queueAhead=0` no longer hides commands waiting behind active work. Fixes #82791. (#82792) Thanks @galiniliev.
- Process/diagnostics: stop counting the active processing turn as queued backlog in liveness warnings so transient max-only event-loop spikes do not surface as gateway warnings.
- Android: prompt before replacing a changed Gateway TLS thumbprint, showing the old and new SHA-256 fingerprints so users can accept expected certificate rotations instead of hard failing on pin mismatch. (#83077) Thanks @sliekens.
- CLI/status: render extra gateway-like service diagnostics as warning/info output instead of error output. Fixes #46930. (#82922) thanks @giodl73-repo.
- Agents/failover: classify Moonshot/Kimi exhausted-balance HTTP 429 payloads as billing instead of generic rate limits, preserving billing guidance and fallback behavior. Fixes #43447. (#83079) Thanks @leno23.
- Plugin SDK: bundle `openclaw/plugin-sdk/zod` into the published package artifact and verify the packed zod subpath stays self-contained, so pnpm global installs can register plugins without a package-local `zod` symlink. Fixes #78398. (#78515) Thanks @ggzeng.
- Providers/Google: drop compaction-truncated Gemini thought signatures before replay so malformed Base64 no longer aborts the next assistant turn. (#82995) Thanks @wAngByg.
- Gateway/mobile: allow paired iOS and Android clients to refresh same-family OS metadata on authenticated reconnect instead of requiring a new approval. (#83490) Thanks @ngutman.
- WhatsApp: treat `upload-file` as a supported media send intent by lowering path/URL uploads through the channel's normal send-media transport. (#81883) Thanks @ngutman.
- iOS: end Live Activities when OpenClaw is connected, idle, or disconnected, and show compact attention states for approval-required reconnects. (#83597) Thanks @ngutman.
- Control UI: hide child nav items when collapsing the active sidebar group. Fixes #42167. (#42223) Thanks @Aroool.
- CI/proof: skip the real-behavior-proof gate for private org maintainers by minting a least-privilege (`members: read`) GitHub App token and checking active membership in the `maintainer` team, instead of treating `author_association=CONTRIBUTOR` as definitively external. (#83418) Thanks @romneyda.
- Agents/Azure OpenAI Responses: default unset Azure OpenAI API versions to `preview` so `/openai/v1/responses` calls use Azure's current Responses API route. (#82026) Thanks @leoge007.
- Control UI/WebChat: compact the desktop chat header controls into a single aligned row so the session, model, thinking, and action controls no longer waste vertical space. Thanks @BunsDev.
- Control UI/settings: widen the Personal quick-settings card to a 3/1 desktop split and keep Appearance/Automations below it on narrower layouts. Thanks @BunsDev.
- Agents: retry empty final turns for generic `anthropic-messages` providers instead of limiting non-visible recovery to Kimi, so custom/proxied Anthropic-compatible routes can recover with a visible answer. Addresses #46080. Thanks @wmgx, @w1tv, and @iFwu.
- Agents/replies: strip workflow `<function_response>` scaffolding from user-visible sanitizer paths so raw tool output does not leak into chat history, transcript mirrors, or channel replies. Fixes #47444. Thanks @5toCode.
- CLI/plugins: route lazy plugin command-registration chatter to stderr only during JSON-output command registration, keeping plugin-backed `--json` stdout parseable without changing parse-only or pass-through `--json` behavior. Fixes #81535. (#81536) Thanks @ScientificProgrammer and @vincentkoc.
- Plugins: treat git plugin install refs as refs instead of checkout flags, so option-like selectors fail checkout instead of silently installing the default branch. Fixes #79898. (#79901) Thanks @afurm and @vincentkoc.
- Doctor/memory: stop warning that no memory plugin is active when an enabled alternate memory plugin explicitly owns the memory slot, while preserving the warning for missing or disabled slot entries. Fixes #78540. (#78557) Thanks @carladams1299-lab and @vincentkoc.
- Plugins: keep process-local plugin metadata snapshot memo freshness tied to the cached registry snapshot so policy-stale derived plugin metadata edits invalidate the memo instead of returning stale owners or command aliases. (#81064) Thanks @Kaspre.
- Plugins: keep derived plugin metadata snapshots uncached when the persisted registry is missing, disabled, or stale, so newly added plugins are discovered without restarting. (#81064) Thanks @Kaspre.
- Plugins: discover provider plugins from `setup.providers[].envVars` credentials during provider discovery while keeping the deprecated `providerAuthEnvVars` fallback. (#81542) Thanks @JARVIS-Glasses.
- Docs/Codex harness: clarify that per-agent `CODEX_HOME` isolates `~/.codex` while inherited `HOME` intentionally keeps `.agents` discovery and subprocess user-home state available.
- CLI/plugins: keep bare plugin and parent-command help on the lightweight path, avoiding plugin registry discovery before rendering help.
- Agents/compaction: cap summarization output reserve tokens to the selected model's `maxTokens` so 1M-context Anthropic compactions do not request more output than the API permits. Fixes #54383.
- Control UI/login: replace raw connection failures with structured, actionable login guidance for auth, pairing, insecure HTTP, origin, protocol, and transport failures. Thanks @BunsDev.
- Agents/tools: fail `exec host=node` before `system.run` when the selected node is known to be disconnected, with an actionable reconnect message instead of a raw node invoke failure. Thanks @BunsDev.
- Agents/tool-result guard: ignore internal tool-result `details` when estimating model-visible context, so large diagnostic metadata no longer triggers unnecessary truncation or compaction even though the provider boundary already strips `details` before model conversion. (#75525) Thanks @zqchris.
- Agents/models: accept legacy `anthropic-cli/*` model refs as Claude CLI runtime refs instead of failing model resolution with `Unknown model`. Thanks @BunsDev.
- Agents/tools: keep restrictive-profile tool-section warnings scoped to the configured sections whose tools are still missing from `alsoAllow`, so already re-allowed filesystem tools do not make exec-only fixes look broader than they are. Thanks @BunsDev.
- Agents/tools: avoid warning messaging-only agents about inherited global `tools.exec` or `tools.fs` sections when the agent profile did not configure those tool sections itself. Thanks @BunsDev.
- Dependencies: bump transitive `basic-ftp` to 5.3.1 so the runtime lockfile no longer includes the vulnerable 5.3.0 build flagged by the production dependency audit. (#78637) Thanks @sallyom.
- Hooks/cron: log returned `/hooks/agent` isolated-run errors and failed cron jobs with cron diagnostic summaries, so rejected `payload.model` values are visible instead of looking like accepted-but-missing runs. Fixes #78597. (#78655) Thanks @kevinslin.
- Managed proxy/security: classify raw socket callsites and proxy runtime mutations in boundary checks so new direct egress or unmanaged proxy-state changes cannot land without explicit review. (#77126) Thanks @jesse-merhi.
- Memory indexing: propagate memory directory creation failures immediately instead of reporting an unusable directory as ready. Thanks @he-yufeng.
- Channels/iMessage: surface the silent group-allowlist drop at default log level by emitting a one-time `warn` per account at monitor startup when `channels.imessage.groupPolicy: "allowlist"` is set without a `channels.imessage.groups` block, plus a one-time `warn` per `chat_id` when the runtime gate drops a specific group, naming the exact `channels.imessage.groups[...]` key to add to allow it. Fixes #78749. (#79190) Thanks @omarshahine.
- WhatsApp: stop Gateway-originated outbound echoes from advancing inbound activity in `openclaw channels status`, so outbound self-sends no longer look like handled inbound messages. Fixes #79056. (#79057) Thanks @ai-hpc and @bittoby.
- Gateway/nodes: preserve the live node registry session and invoke ownership when an older same-node WebSocket closes after reconnecting. (#78351) Thanks @samzong.
- Browser/chrome-mcp: read Chrome DevTools MCP screenshot output from the extension-suffixed path, fixing ENOENT on screenshot capture. Fixes #77222. (#74685) Thanks @barbarhan.
- Agents/OpenAI: honor `compat.supportsTools: false` for OpenAI Completions models so chat-only compatible endpoints do not receive `tools`, `tool_choice`, or tool-history fallback payloads. Fixes #74664. Thanks @yelog.
- macOS/launchd: set generated Gateway LaunchAgent plists to `ProcessType=Interactive` so the gateway keeps timely execution during idle periods. Fixes #58061; refs #62294 and closed duplicate #66992. (#62308) Thanks @bryanpearson and @zssggle-rgb.
- 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.
- Diffs plugin: accept `defaults.ttlSeconds` as a plugin-wide artifact lifetime default, so LAN-viewable diff links can keep their configured six-hour TTL without doctor quarantining the plugin entry. (#77456) Thanks @VACInc.
- Gate zalouser startup name matching [AI]. (#77411) Thanks @pgondhi987.
- Active Memory: send a bounded latest-message search query to the recall worker so channel/runtime metadata does not become the memory search string. Fixes #65309. Thanks @joeykrug, @westley3601, @pimenov, and @tasi333.
- Memory/QMD: report missing or invalid agent workspace directories as workspace probe failures in doctor/QMD availability checks instead of sending operators toward binary-install fixes. Fixes #63158. Thanks @sercada.
- Providers/OpenRouter: keep DeepSeek V4 `reasoning_effort` on OpenRouter-supported values, mapping stale `max` thinking overrides to `xhigh` so `openrouter/deepseek/deepseek-v4-pro` no longer fails with OpenRouter's invalid-effort 400. Fixes #77350. (#77423) Thanks @krllagent, @mushuiyu886, and @sallyom.
- CLI/message: skip eager model context warmup and preserve channel-declared gateway execution for Discord and Telegram message actions, avoiding Codex app-server/model discovery during simple send/read commands. Thanks @fuller-stack-dev.
- Agents/exec approvals: parse exec approval result metadata with balanced parentheses so nested-paren denial and finished payloads such as `Exec denied (gateway id=req-1, approval-timeout (allowlist-miss)): ...` are matched and routed to the denied followup branch instead of falling through to the generic followup path. (#72268) Thanks @amittell.
- Codex/app-server: resolve managed binaries from bundled `dist` chunks and from the `@openai/codex` package bin when installs do not provide a nearby `.bin/codex` shim, avoiding false missing-binary startup failures.
- Plugins/ClawHub: use the ClawHub artifact resolver response as the install decision before downloading, keeping legacy ZIP fallback and future ClawPack npm-pack installs on the same explicit resolver path. Thanks @vincentkoc.
- Plugins/ClawHub: keep bare plugin package specs on npm for the launch cutover and reserve ClawHub resolution for explicit `clawhub:` specs until ClawHub pack readiness is deployed. Thanks @vincentkoc.
- Skills/OpenAI Whisper: restore executable bits for bundled Whisper and video-frame shell helpers and add a release check for non-executable bundled skill shell scripts, so packaged installs no longer fail with permission-denied errors. Fixes #9303. Thanks @nikolasdehor.
- Agents/tools: skip unavailable media generation and PDF tool factories from the live reply path when Gateway metadata and the active auth store prove no configured provider can back them, while keeping explicit config and auth-backed providers on the normal factory path. Thanks @shakkernerd.
- Agents/runtime: reuse the Gateway metadata startup plan when ensuring reply runtime plugins are loaded, so live agent turns do not broad-load plugin runtimes after the Gateway already scoped startup activation. Thanks @shakkernerd.
- Agents/runtime: delegate scoped reply runtime registry reuse to the plugin loader cache-key compatibility checks, so config changes with the same startup plugin ids cannot keep stale runtime hooks or tools active. Thanks @shakkernerd.
- CLI/plugins: refresh persisted plugin registry policy in place for `plugins enable` and `plugins disable`, so routine toggles no longer rebuild and hash every plugin source when the target is already indexed. Thanks @vincentkoc.
- Windows/install: run npm from a writable installer temp directory and pin the Bedrock runtime dependency below a Windows ARM Node 24 npm resolver failure, so global OpenClaw installs no longer fail before onboarding. Thanks @mariozechner.
- CLI/plugins: scope install and enable slot selection to the selected plugin manifest/runtime fallback, so plugin installs no longer load every plugin runtime or broad status snapshot just to update memory/context slots. Thanks @vincentkoc.
- Browser/snapshot: propagate the configured snapshot timeout through the agent tool, Chrome MCP, and Playwright snapshot paths so snapshot actions honor the requested deadline instead of hanging. Fixes #72934. Thanks @masatohoshino.
- Plugins/TTS: keep bundled speech-provider discovery available on cold package Gateway paths and add bundled plugin matrix runtime probes for health, readiness, RPC, TTS discovery, and post-ready runtime-deps watchdog coverage. Refs #75283. Thanks @vincentkoc.
- Google Meet/Twilio: show delegated voice call ID, DTMF, and intro-greeting state in `googlemeet doctor`, and avoid claiming DTMF was sent when no Meet PIN sequence was configured. Refs #72478. Thanks @DougButdorf.
- Plugins/tools: prefer built bundled plugin code during tool discovery and skip channel runtime hydration while preserving companion provider registrations, reducing per-run plugin-tool prep cost without dropping executable plugin tools. Fixes #75290. Thanks @thanos-openclaw.
- Agents/LSP: terminate bundled stdio LSP process trees during runtime disposal and Gateway shutdown, so nested children such as `tsserver` do not survive stop or restart. Fixes #72357. Thanks @ai-hpc and @bittoby.
- Diagnostics/OTEL: capture privacy-safe model-call request payload bytes, streamed response bytes, first-response latency, and total duration in diagnostic events, plugin hooks, stability snapshots, and OTEL model-call spans/metrics without logging raw model content. Fixes #33832. Thanks @wwh830.
- Logging: write validated diagnostic trace context as top-level `traceId`, `spanId`, `parentSpanId`, and `traceFlags` fields in file-log JSONL records so traced requests and model calls are easier to correlate in log processors. Refs #40353. Thanks @liangruochong44-ui.
- Nextcloud-Talk: wire the existing reaction sender into the channel `actions` adapter so agents can react to messages via the shared `message` tool, instead of advertising the `reactions` capability without a dispatch path. Fixes #70110. Thanks @powerpaul17.
- Logging/sessions: apply configured redaction patterns to persisted session transcript text and accept escaped character classes in safe custom redaction regexes, so transcript JSONL no longer keeps matching sensitive text in the clear. Fixes #42982. Thanks @panpan0000.
- Providers/Ollama: honor `/api/show` capabilities when registering local models so non-tool Ollama models no longer receive the agent tool surface, and keep native Ollama thinking opt-in instead of enabling it by default. Fixes #64710 and duplicate #65343. Thanks @yuan-b, @netherby, @xilopaint, and @Diyforfun2026.
- Control UI/Agents: remount the Overview model controls when switching agents so the primary-model picker cannot retain stale per-agent selection. Fixes #39392; carries forward #39401, notes the duplicate #39495 approach, and keeps #46275/#54724 broader stabilization out of scope. Thanks @daijunyi002, @SergioChan, @aworki, and @wsyjh8.
- Providers/SDK retry: cap long `Retry-After` sleeps in Stainless-based Anthropic/OpenAI model SDKs so 60s+ retry windows surface immediately for OpenClaw failover instead of blocking the run. (#68474) Thanks @jetd1.
- Agents/TTS: preserve spoken text in TTS tool results while defusing reply directives in transcript content, so future turns remember voice replies without treating spoken `MEDIA:` or voice tags as delivery metadata. (#68869) Thanks @zqchris.
- Providers/OpenAI: harden Voice Call realtime transcription against OpenAI Realtime session-update drift, forward language and prompt hints, and add live coverage for realtime STT.
- Agents/Pi embedded runs: suppress the "âš ï¸ Agent couldn't generate a response" warning when the assistant already delivered user-visible content through a messaging tool and the turn ended cleanly (`stopReason=stop`). Real failure modes (tool errors, provider `stopReason=error`, interrupted tool use) still surface the existing "verify before retrying" warning. Fixes #70396. (#70425) Thanks @neeravmakwana.
- Agents/Pi embedded runs: suppress the "⚠️ Agent couldn't generate a response" warning when the assistant already delivered user-visible content through a messaging tool and the turn ended cleanly (`stopReason=stop`). Real failure modes (tool errors, provider `stopReason=error`, interrupted tool use) still surface the existing "verify before retrying" warning. Fixes #70396. (#70425) Thanks @neeravmakwana.
- Auto-reply/WebChat: preserve the active session mapping when context-overflow recovery or auto-compaction fails, and return retry, `/compact`, and `/new` guidance instead of silently rotating to a fresh session. Fixes #70472. (#70479) Thanks @fuller-stack-dev.
- Gateway/Linux: wrap gateway-managed supervisor, PTY, MCP stdio, and browser child processes in a tiny `/bin/sh` shim that raises the child's own `oom_score_adj` on Linux, so under cgroup memory pressure the kernel prefers transient workers over the long-lived gateway. Opt out with `OPENCLAW_CHILD_OOM_SCORE_ADJ=0`. Fixes #70404. (#70419) Thanks @neeravmakwana.
- Providers/Moonshot: stop strict-sanitizing Kimi's native tool_call IDs (shaped like `functions.<name>:<index>`) on the OpenAI-compatible transport, so multi-turn agentic flows through Kimi K2.6 no longer break after 2-3 tool-calling rounds when the serving layer fails to match mangled IDs against the original tool definitions. Adds a `sanitizeToolCallIds` opt-out to the shared `openai-compatible` replay family helper and wires Moonshot to it. Fixes #62319. (#70030) Thanks @LeoDu0314.
- Dependencies/security: override transitive `uuid` to `14.0.0`, clearing the runtime advisory across dependencies.
- CLI/skills: require unique case-insensitive fallback matches in `openclaw skills info` so case-only collisions return not-found instead of showing guidance for the wrong skill. (#38713)
- Agents/Ollama: forward the configured embedded-run timeout into the global undici stream timeout tuning so slow local Ollama runs no longer inherit the default stream cutoff instead of the operator-set run timeout. (#63175) Thanks @mindcraftreader and @vincentkoc.
- Models/Codex: include `apiKey` in the codex provider catalog output so the Pi ModelRegistry validator no longer rejects the entry and silently drops all custom models from every provider in `models.json`. (#66180) Thanks @hoyyeva.
- Tools/image+pdf: normalize configured provider/model refs before media-tool registry lookup so image and PDF tool runs stop rejecting valid Ollama vision models as unknown just because the tool path skipped the usual model-ref normalization step. (#59943) Thanks @yqli2420 and @vincentkoc.
Model note: while many providers and models are supported, prefer a current flagship model from the provider you trust and already use. See [Onboarding](https://docs.openclaw.ai/start/onboarding).
Model note: while many providers and models are supported, prefer a current flagship model from the provider you trust and already use. See [Onboarding](https://docs.openclaw.ai/start/wizard).
## Install (recommended)
Runtime: **Node 24 (recommended) or Node 22.16+**.
Runtime: **Node 24 (recommended) or Node 22.19+**.
```bash
npm install -g openclaw@latest
@@ -109,15 +109,27 @@ OpenClaw Onboard installs the Gateway daemon (launchd/systemd user service) so i
## Quick start (TL;DR)
Runtime: **Node 24 (recommended) or Node 22.16+**.
Runtime: **Node 24 (recommended) or Node 22.19+**.
Full beginner guide (auth, pairing, channels): [Getting started](https://docs.openclaw.ai/start/getting-started)
Recommended daemon mode:
```bash
openclaw onboard --install-daemon
openclaw gateway status
```
Foreground/debug mode:
```bash
openclaw gateway stop
openclaw gateway --port 18789 --verbose
```
Send a test message or ask the assistant after either startup mode is running:
```bash
# Send a message
openclaw message send --target +1234567890 --message "Hello from OpenClaw"
OpenClaw connects to real messaging surfaces. Treat inbound DMs as **untrusted input**.
Full security guide: [Security](https://docs.openclaw.ai/gateway/security)
Full security guide: [Security](https://docs.openclaw.ai/gateway/security).
Before remote exposure, use the [Gateway exposure runbook](https://docs.openclaw.ai/gateway/security/exposure-runbook).
Default behavior on Telegram/WhatsApp/Signal/iMessage/Microsoft Teams/Discord/Google Chat/Slack:
@@ -159,7 +172,7 @@ Run `openclaw doctor` to surface risky/misconfigured DM policies.
- Default: tools run on the host for the `main` session, so the agent has full access when it is just you.
- Group/channel safety: set `agents.defaults.sandbox.mode: "non-main"` to run non-`main` sessions inside sandboxes. Docker is the default sandbox backend; SSH and OpenShell backends are also available.
- Before exposing anything remotely, read [Security](https://docs.openclaw.ai/gateway/security), [Sandboxing](https://docs.openclaw.ai/gateway/sandboxing), and [Configuration](https://docs.openclaw.ai/gateway/configuration).
- Before exposing anything remotely, read [Security](https://docs.openclaw.ai/gateway/security), [Gateway exposure runbook](https://docs.openclaw.ai/gateway/security/exposure-runbook), [Sandboxing](https://docs.openclaw.ai/gateway/sandboxing), and [Configuration](https://docs.openclaw.ai/gateway/configuration).
## Operator quick refs
@@ -173,7 +186,7 @@ Run `openclaw doctor` to surface risky/misconfigured DM policies.
- New here: [Getting started](https://docs.openclaw.ai/start/getting-started), [Onboarding](https://docs.openclaw.ai/start/wizard), [Updating](https://docs.openclaw.ai/install/updating)
@@ -312,7 +312,7 @@ OpenClaw's web interface (Gateway Control UI + HTTP endpoints) is intended for *
### Node.js Version
OpenClaw requires **Node.js 22.16.0 or later** (LTS). This version includes important security patches:
OpenClaw requires **Node.js 22.19.0 or later** (LTS). Node 24 is the recommended default runtime for new installs. The minimum version includes important security patches:
- CVE-2025-59466: async_hooks DoS vulnerability
- CVE-2026-21636: Permission model bypass vulnerability
@@ -320,7 +320,7 @@ OpenClaw requires **Node.js 22.16.0 or later** (LTS). This version includes impo
- Google Play treats SMS and Call Log access as highly restricted. In most cases, Play only allows them for the default SMS app, default Phone app, default Assistant, or a narrow policy exception.
- Review usually involves a `Permissions Declaration Form`, policy justification, and demo video evidence in Play Console.
-If we want a Play-safe build, these should be the first permissions removed behind a dedicated product flavor / variant.
-The Play build removes these behind the `play` flavor.
- Photo library access is also removed from the Play build. Use third-party builds for `photos.latest`.
Current OpenClaw Android implication:
- APK / sideload build can keep SMS and Call Log features.
- Google Play build should exclude SMS send/search and Call Log search unless the product is intentionally positioned and approved as a default-handler exception case.
- APK / sideload build can keep SMS, Call Log, and recent-photo features.
- Google Play build excludes SMS send/search, Call Log search, and recent-photo access unless the product is intentionally positioned and approved under the relevant policy exception.
- The repo now ships this split as Android product flavors:
-`play`: removes `READ_SMS`, `SEND_SMS`, and`READ_CALL_LOG`, and hides SMS / Call Log surfaces in onboarding, settings, and advertised node capabilities.
-`thirdParty`: keeps the full permission set and the existing SMS / Call Log functionality.
-`play`: removes `READ_SMS`, `SEND_SMS`, `READ_CALL_LOG`, `READ_MEDIA_IMAGES`, `READ_MEDIA_VISUAL_USER_SELECTED`, and `READ_EXTERNAL_STORAGE`; hides SMS, Call Log, and Photos surfaces in onboarding, settings, and advertised node capabilities.
-`thirdParty`: keeps the full permission set and the existing SMS / Call Log / Photos functionality.
Policy links:
@@ -252,12 +253,13 @@ Pre-req checklist:
5) Grant runtime permissions for capabilities you expect to pass (camera/mic/location/notification listener/location, etc.).
6) No interactive system dialogs should be pending before test start.
7) Canvas host is enabled and reachable from the device (do not run gateway with `OPENCLAW_SKIP_CANVAS_HOST=1`; startup logs should include `canvas host mounted at .../__openclaw__/`).
8) Local operator test client pairing is approved. If first run fails with `pairing required`, approve latest pending device pairing request, then rerun:
8) Local operator test client pairing is approved. If first run fails with `pairing required`, preview the latest pending request, approve the printed request ID, then rerun:
9) For A2UI checks, keep the app on **Screen** tab; the node now auto-refreshes canvas capability once on first A2UI reachability failure (TTL-safe retry).
```bash
openclaw devices list
openclaw devices approve --latest
openclaw devices approve --latest# preview only; copy the requestId from output
openclaw devices approve <requestId>
```
Run:
@@ -283,7 +285,7 @@ What it does:
Common failure quick-fixes:
-`pairing required` before tests start:
-approve pending device pairing (`openclaw devices approve --latest`) and rerun.
-list pending requests (`openclaw devices list`), then approve with the exact ID (`openclaw devices approve <requestId>`) and rerun.
-`A2UI host not reachable` / `A2UI_HOST_NOT_CONFIGURED`:
- ensure the Canvas plugin host is running and reachable, keep the app on the **Screen** tab. The app refreshes the Canvas plugin surface URL once before failing; if it still fails, reconnect app and rerun.
privatefunchannelsWarningText(summary:GatewayChannelsSummary):String=summary.warnings.firstOrNull()?.takeIf{it.isNotBlank()}?:"Some channel status checks did not complete."
Text(text="View all models",style=ClawTheme.type.caption.copy(fontSize=12.5.sp,lineHeight=16.sp),color=ClawTheme.colors.textMuted,modifier=Modifier.weight(1f))
Icon(imageVector=Icons.AutoMirrored.Filled.KeyboardArrowRight,contentDescription="View all models",modifier=Modifier.size(14.dp),tint=ClawTheme.colors.text)
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.