Summary:
- Adds a scoped ModelStudio/DashScope OpenAI-compatible guard for chat payloads with no non-empty user or assi ... turn, shared turn-detection helper coverage, prompt-skip handling, regression tests, and a changelog entry.
- PR surface: Source +83, Tests +298, Docs +1. Total +382 across 10 files.
- Reproducibility: yes. source-reproducible for the OpenClaw-side malformed payload shape: current main has no ... he exact qwen-long/qwen3-coder-plus provider error was not reproduced with the available DashScope account.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: make OpenAI payload guard content-aware
- PR branch already contained follow-up commit before automerge: fix: scope openai payload turn guard
- PR branch already contained follow-up commit before automerge: Guard OpenAI chat payload turns
Validation:
- ClawSweeper review passed for head e16a3fe9f2.
- Required merge gates passed before the squash merge.
Prepared head SHA: e16a3fe9f2
Review: https://github.com/openclaw/openclaw/pull/86497#issuecomment-4534668405
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: Onur Solmaz <2453968+osolmaz@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: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Reverts the diagnostic queue-pressure suppression of non-terminal session tool mirrors from PR 84846 while keeping PR 86503 recipient dedupe intact. Session-only Control UI subscribers keep receiving tool lifecycle mirrors; overlapping run and session subscribers still receive one canonical run-scoped frame. Verification: focused gateway and diagnostic tests, diff check, changed check, and autoreview all passed.
* fix(agents): release embedded-attempt session lock on every exit path
The embedded run controller acquires its session write lock eagerly at
creation and released it only inside the post-run cleanup block. An
exception thrown in post-prompt processing skipped that block, so the lock
leaked to the live gateway process until the watchdog reclaimed it and
later requests to the session failed with SessionWriteLockTimeoutError.
Add an idempotent dispose() to the lock controller and call it from the
run's outer finally so the eagerly-held lock is released on every exit
path. Normal/aborted/timed-out runs still hand the lock to
acquireForCleanup first, so dispose() is a no-op then (no double release).
Fixes#86014
* fix: keep session lock teardown comment lean
* docs(changelog): note embedded session lock fix
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Dedupe gateway tool-event fanout so connections subscribed by both run and session receive the canonical run-scoped agent event only, while session-only subscribers keep the compatibility session.tool mirror.\n\nVerification:\n- node scripts/run-vitest.mjs src/gateway/server-chat.agent-events.test.ts\n- git diff --check\n- env -u OPENCLAW_TESTBOX pnpm check:changed\n- .agents/skills/autoreview/scripts/autoreview --mode local
Summary:
- The PR expands security audit, CLI docs, and tests so `hooks.token` reuse of active Gateway token/password auth is reported while password-mode Gateway startup remains compatible.
- PR surface: Source +178, Tests +311, Docs +14. Total +503 across 14 files.
- Reproducibility: yes. from source inspection: current main forwards a bearer token as both token and passwor ... ecause this review was read-only, but the linked issue and code path make the reproduction high confidence.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cr-fmi-hook-ingress-token-unlocks-password-mode-gateway-auth): ap…
- PR branch already contained follow-up commit before automerge: fix: include trusted proxy password in hooks token reuse check
- PR branch already contained follow-up commit before automerge: fix(gateway): audit hooks password reuse without blocking startup
- PR branch already contained follow-up commit before automerge: fix: Hook ingress token unlocks password-mode gateway auth
Validation:
- ClawSweeper review passed for head 7c796b22ec.
- Required merge gates passed before the squash merge.
Prepared head SHA: 7c796b22ec
Review: https://github.com/openclaw/openclaw/pull/86453#issuecomment-4533831028
Co-authored-by: Coy Geek <65363919+coygeek@users.noreply.github.com>
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
* fix(diagnostics): reclaim wedged session lanes with a stale leaked active run
A group session lane could wedge permanently (#85639): an embedded run that dies
abnormally leaves a stale ACTIVE_EMBEDDED_RUNS handle, so the diagnostic heartbeat
classifies the lane stale_session_state (recoveryEligible without allowActiveAbort)
while stuck-session recovery reads the leaked isEmbeddedPiRunActive flag and skips
with active_reply_work — a tautology that keeps the lane forever. The age-based
escape never fires because ageMs (last-activity) resets on every incoming queued
message.
Make the active-run skip a liveness check: before keeping the lane, consult the
run's real forward-progress age (lastProgressAgeMs, not refreshed by incoming
messages). If a run flagged active has made no forward progress past the resolved
diagnostics.stuckSessionAbortMs threshold (threaded through the recovery request;
falls back to a 5-minute floor) with queued work waiting, treat it as a
leaked/dead handle and reclaim it (abort + drain + force-clear) instead of
skipping. A genuinely progressing run, or one within an operator-raised
threshold, is kept.
Fixes#85639
* test(diagnostics): cover stale active run recovery
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The PR adds HEIC/HEIF-to-JPEG normalization before media-understanding image description providers run, with regression tests and a changelog entry.
- PR surface: Source +58, Tests +82, Docs +1. Total +141 across 6 files.
- Reproducibility: yes. at source level: current main forwards HEIC buffers to `describeImage` without normali ... ody includes a red HEIC regression test before the patch. I did not execute tests in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(media-understanding): normalize HEIC before image descriptions
Validation:
- ClawSweeper review passed for head ed34620bd7.
- Required merge gates passed before the squash merge.
Prepared head SHA: ed34620bd7
Review: https://github.com/openclaw/openclaw/pull/86037#issuecomment-4528578874
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>
- Rotate OpenAI Realtime voice sessions on provider max-duration events without surfacing the expected expiry as a Discord voice error.
- Add lifecycle logging for Realtime rotation/reconnect and regression coverage for max-duration reconnect.
- Allowlist the existing Control UI chunking helper for the optional Knip unused-file guard so the dependency shard stays green on the current base.
Catch non-ENOENT load failures inside maybeRepairLegacyCronStore so an
unreadable ~/.openclaw/cron/jobs.json (e.g. root-owned 0600 inside
Docker) no longer aborts the rest of the doctor health checks. The
scheduler-side loadCronStore keeps its strict throw-on-read-failure
contract.
Closes#86102
Co-authored-by: 1052326311 <1052326311@users.noreply.github.com>
After config.patch writes new values to openclaw.json, a subsequent
SIGUSR1 in-process restart could overwrite them with a stale snapshot.
Root cause: run-loop's onIteration hook resets lanes and task registry,
but leaves the runtimeConfigSnapshot intact. loadConfig() then returns
the old snapshot via loadPinnedRuntimeConfig() instead of re-reading disk.
Fix: clearRuntimeConfigSnapshot() in the restart iteration hook so the
next startup reads fresh config from disk.
Refs #86350
Summary:
- The PR routes local GGUF memory embeddings through a bundled worker sidecar, adds structured degradation and fallback handling, updates memory tests/build output, and keeps the local config contract unchanged.
- PR surface: Source +831, Tests +503, Docs +1, Other +2. Total +1337 across 23 files.
- Reproducibility: Do we have a high-confidence way to reproduce the issue? Source and report evidence are str ... cludes native crash logs; the exact Metal teardown abort was not reproduced in this review or the PR proof.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(memory): keep local embedding config unchanged
- PR branch already contained follow-up commit before automerge: fix(memory): type local embedding degradation
- PR branch already contained follow-up commit before automerge: fix(memory): refresh keywords after embedding fallback
- PR branch already contained follow-up commit before automerge: fix(memory): keep worker errors internal
- PR branch already contained follow-up commit before automerge: test: satisfy memory provider lifecycle harnesses
- PR branch already contained follow-up commit before automerge: fix: harden local embedding worker fallback
Validation:
- ClawSweeper review passed for head 1d1fe41c4e.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1d1fe41c4e
Review: https://github.com/openclaw/openclaw/pull/85348#issuecomment-4518516047
Co-authored-by: Onur Solmaz <onur@Onurs-MacBook-Pro.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: osolmaz
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
* fix(memory-core): filter REM dreaming candidates to light-staged entries
REM dreaming re-ingested the full short-term recall store independently,
ignoring which entries were staged by the light sleep phase. Because the
confidence formula heavily weights accumulated averageScore (45%) and
recallStrength (25%), old high-recall entries permanently dominated
freshly staged candidates. The intended light→REM→deep pipeline was
broken: light correctly staged current material, but REM selected a
different set entirely, so lightHits never paired with remHits for deep
ranking.
Fix: in runRemDreaming(), read the phase-signals store for keys with
lightHits > 0 and filter entries to that set before passing to
previewRemDreaming(). When no light-staged keys exist (light disabled
or first run), fall back to the full entry set for backward
compatibility.
Added readLightStagedKeys() to short-term-promotion.ts as a clean
export for reading the light-staged key set from the phase signal store.
Closes#86249
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(memory-core): keep REM staging pending
* fix(memory-core): mark REM-considered staged entries
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(telegram): propagate forum topic names into agent context
The topic-name-cache already tracks forum topic names via
forum_topic_created/edited/closed events in bot-message-context, but
this metadata was not surfaced in two key paths:
1. The native-command handler (bot-native-commands.ts) builds the agent
context payload with IsForum but never looked up the cached topic
name. Now it resolves the topic name from the cache and includes
TopicName in the context, giving agents awareness of which forum
topic they are responding in.
2. The action runtime (action-runtime.ts) executes createForumTopic and
editForumTopic actions but never persisted the resulting topic
metadata back to the cache. Now both actions write the topic name
(and optional icon metadata) to the cache after success, ensuring
subsequent messages in those topics can resolve the name.
Closes#86024
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(telegram): scope forum topic cache updates
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Co-authored-by: Peter Steinberger <steipete@gmail.com>