Fixes#90685 by allowing models.list availability to use matching auth-profile credentials when provider config contains a non-env SecretRef, while preserving unavailable results for unresolved SecretRef-only providers.
Adds isolated regression coverage for file SecretRefs and secretref-managed provider markers.
Co-authored-by: Rohit <rohitjavvadi2@gmail.com>
Persist successful same-channel Slack and CLI assistant replies exactly once in the owning transcript. Preserve delivery-hook output, routed/runtime ownership, custom stores, and authoritative reset/session rotation bindings.
Fixes#92489
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Non-control-UI-visible runs previously dropped assistant commentary on the
floor for session message subscribers. Mirror those events to exact session
subscribers, gated strictly on phase === "commentary" so untagged text or
delta frames and final-answer streaming never dual-lane into channel
surfaces. Dialects that emit commentary as untagged deltas should tag the
phase at provider normalization instead.
Co-authored-by: Forge <forge@psiclawops.dev>
Co-authored-by: Chisel <chisel@psiclawops.dev>
* fix(control-ui): make bootstrap config endpoint base-path-relative (#66946)
CONTROL_UI_BOOTSTRAP_CONFIG_PATH embedded a hard-coded /__openclaw prefix
instead of being base-path-relative. When the Control UI is served under
/__openclaw__/, both the gateway and the browser loader compose
${basePath}${CONTROL_UI_BOOTSTRAP_CONFIG_PATH}, producing the doubled
/__openclaw__/__openclaw/control-ui-config.json URL that 404s.
Make the constant base-path-relative (/control-ui-config.json) so the
composed URL is correct under any base path, align the Vite dev stub and
the docs, and add gateway.controlUi.basePath "/__openclaw__" coverage.
* fix(control-ui): serve bootstrap config at default __openclaw__ entry (#66946)
The reporter runs the default deployment (no gateway.controlUi.basePath),
so the Control UI SPA is mounted under the default /__openclaw__/ namespace.
A browser opening that entry infers basePath="/__openclaw__" from the URL
(inferBasePathFromPathname) and fetches /__openclaw__/control-ui-config.json,
but an empty-base-path gateway only served the bare /control-ui-config.json,
so the default-entry bootstrap request 404'd and chat never finished loading.
Make handleControlUiHttpRequest also accept the default-namespace alias
/__openclaw__/control-ui-config.json when no base path is configured. The
alias is derived from the existing CONTROL_UI_NAMESPACE_PREFIX mount constant
and is purely additive: the bare /control-ui-config.json endpoint and the
configured-base-path endpoint are both preserved (no route removed).
Add gateway HTTP coverage for the real default-entry scenario (empty base
path + /__openclaw__/... request) that fails without the alias, alongside the
configured-base-path, bare-path compatibility, and doubled-path 404 cases.
* fix(control-ui): preserve legacy bootstrap endpoint as compat alias (#66946)
Current main and v2026.6.1 serve and document the single-underscore
/__openclaw/control-ui-config.json bootstrap endpoint under an empty
base path (that literal was CONTROL_UI_BOOTSTRAP_CONFIG_PATH before the
path was made base-path-relative). Making the constant relative dropped
that match, so older bundles and clients hitting the documented endpoint
would 404 after upgrading.
Accept the legacy single-underscore path as an empty-base-path
compatibility alias in matchesControlUiBootstrapConfigPath, derived from
the legacy /__openclaw namespace joined with the canonical config
constant (so it tracks any filename rename) and named
LEGACY_BOOTSTRAP_CONFIG_PATH with a comment. The canonical
/control-ui-config.json and the default-namespace
/__openclaw__/control-ui-config.json aliases are unchanged; only this
path is added. The doubled /__openclaw__/__openclaw/... path still 404s.
Add a focused regression that the legacy endpoint returns config under an
empty base path; it 404s without the alias (verified non-vacuous).
* fix(control-ui): preserve legacy bootstrap route under configured base path (#66946)
The previous revision preserved the single-underscore
/__openclaw/control-ui-config.json bootstrap endpoint only under an empty
base path. A deployment with a configured gateway.controlUi.basePath
(e.g. /x) served and documented that endpoint at
${basePath}/__openclaw/control-ui-config.json before this PR made the
config path base-path-relative, so configured-base-path users, older
bundles, and clients that still request it would 404 after upgrading.
Extend matchesControlUiBootstrapConfigPath so the legacy single-underscore
suffix is accepted under every base path, not just the empty one. The
matcher now checks the canonical and legacy suffixes uniformly as
${basePath}${CONTROL_UI_BOOTSTRAP_CONFIG_PATH} and
${basePath}${LEGACY_BOOTSTRAP_CONFIG_PATH} for both the empty and
configured cases, reusing the existing LEGACY_BOOTSTRAP_CONFIG_PATH
constant (no new hard-coded literal). The default-namespace
/__openclaw__/control-ui-config.json alias stays empty-base-path-only
(it is the path the inferred default entry requests when no base path is
configured). All three empty-base-path behaviors are unchanged; the
doubled /__openclaw__/__openclaw/... path still 404s under both an empty
and a configured base path.
Add a focused regression that the configured-base-path legacy endpoint
returns the bootstrap config; it 404s without the alias (verified
non-vacuous). No CHANGELOG.md change.
* fix(ui): mount config stub under vite base
* fix(ui): preserve default config stub route
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
A chokidar watcher 'error' permanently disabled config hot-reload with a
single warn. Re-create the watcher with bounded backoff (500ms/2s/5s, 3
retries); on exhausted budget escalate to log.error and flip a persistent
hotReloadStatus to disabled. stop() clears any pending re-create timer.
Capture the originating sessionKey and agentId for cron wake tool calls so non-main session and multi-agent wakes return to the conversation lane that requested them.
Carry stored delivery context through queued wake events so topic/thread replies route correctly, while preserving the default no-origin wake behavior and explicit target:none opt-out.
Refs #46886.
Refs #64556.
Thanks @anagnorisis2peripeteia.
Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
* fix(cron): reject cron expressions with no reachable run time
A structurally valid but never-matching cron expression (for example
"0 0 30 2 *", Feb 30) was accepted at registration and then silently never
fired: the job showed as enabled but never ran, never appeared in the run
log, and was never auto-disabled.
croner constructs these expressions without error and nextRun() returns null,
so computeNextRunAtMs returns undefined with no throw, and the scheduler
treated it as "no work to do".
Add a satisfiability assertion at the shared service validation boundary
(createJob and applyJobPatch) so every create/update path and every caller
(gateway RPC, CLI, and the in-process host-hook and dreaming callers that
bypass the RPC layer) rejects an expression with no upcoming run time.
applyJobPatch only asserts when the patch changes the schedule, so a job that
predates this change can still be disabled or repaired. The thrown message is
classified by the gateway as INVALID_REQUEST.
* fix(cron): validate enabled schedules with service clock
* fix(cron): keep schedule validation service-owned
* fix(cron): validate staggered schedule reachability
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary:
- The PR adds an explicit user-intent argument to `createChatSession`, updates the New Chat and `/new` action callers to pass it, adds helper regression coverage, and carries minor gateway formatting/import ordering churn.
- PR surface: Source +8, Tests +9. Total +17 across 8 files.
- Reproducibility: yes. at source level: current main lets `createChatSession(state)` reach `sessions.create` ... ct flow, so the exact user-path reproduction remains integration-level rather than locally reproduced here.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test(tasks): restore timers before maintenance apply
- PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into HEAD
Validation:
- ClawSweeper review passed for head e7cd79006b.
- Required merge gates passed before the squash merge.
Prepared head SHA: e7cd79006b
Review: https://github.com/openclaw/openclaw/pull/91480#issuecomment-4651778423
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>