Commit Graph

41053 Commits

Author SHA1 Message Date
Vincent Koc
d5e3c68632 fix(daemon): block conflicting systemd gateway owners (#116162) 2026-07-30 09:53:38 +08:00
Vincent Koc
51f9f061f0 docs(config): clarify user timezone contract (#116160) 2026-07-30 09:49:18 +08:00
Vincent Koc
12e5eb6a23 fix(ui): clarify model setup flows (#116086) 2026-07-30 09:47:57 +08:00
joshavant
21db50efc7 refactor(whatsapp): keep inbound boundary transport-private 2026-07-29 20:34:55 -05:00
Vincent Koc
f970e5093b refactor(channels): add portable inbound boundary 2026-07-29 20:34:55 -05:00
Vincent Koc
f4969c33d9 fix(sessions): migrate legacy transcripts during SQLite import (#116077) 2026-07-30 09:28:47 +08:00
xin zhuang
2e1bf01f51 fix(config): allow explicit main agent bindings when agents.list is non-empty (#89419)
* fix(config): preserve explicit main route bindings

* fix(config): preserve configured main-like agent bindings

* test(routing): cover implicit main roster precedence

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 09:15:44 +08:00
Vincent Koc
3f918d4b3c fix(hooks): honor user timezone in session memory (#116136) 2026-07-30 09:04:52 +08:00
Yuval Dinodia
8ce1e18d2f fix(agents): apply_patch rewrites bytes on hunk context lines (#116128)
* fix(agents): apply_patch rewrites bytes on hunk context lines

A fuzzy apply_patch update replaced the entire matched span with the
model-authored patch text, so trailing whitespace, typographic punctuation,
and tab indentation on lines the hunk marked as context were overwritten
while the tool reported plain success.

The parser now records which emitted lines came in as context and which old
line each one came from, and the update applier keeps the file's own bytes
for those lines. Added and removed lines are still written from the patch.

* test(agents): cover apply_patch context preservation

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 09:04:04 +08:00
Wynne668
77ec4c5420 fix(config): reject invalid heartbeat activeHours without cadence (#102319)
* fix(config): validate heartbeat activeHours without cadence

* fix(config): repair invalid heartbeat active hours

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 08:54:36 +08:00
Ayaan Zaidi
06a5b974ad fix(proxy): keep the capture header predicate module-private
Only the shared redaction helper needs to be public; the name predicate is
an implementation detail and an unused export trips the dependency check.
2026-07-30 09:48:33 +09:00
Ayaan Zaidi
879894a5bd fix(proxy): redact sensitive headers in standalone debug proxy captures
The standalone debug proxy wrote raw request and response headers into
capture rows while the patched-fetch runtime redacted at the parallel
call sites, so a capture taken through the proxy could persist
Authorization, Cookie, and API-key values to disk.

Move the runtime's redaction policy into a leaf module both writers
import instead of adding a second copy, so the two capture paths cannot
drift. The shared helper also flattens node's array-valued headers,
which the standalone proxy passes in directly, and keeps value-level
registered-secret redaction for header names that are not themselves
sensitive.

Reported by SebTardif in #90009; supersedes #82951, which redacted only
by header name and predates the proxy-server rewrite.
2026-07-30 09:48:33 +09:00
Josh Boys
edbb1fca86 fix(doctor): fail closed on unknown channel schema (#116025)
doctor --fix copies allowFrom into groupAllowFrom for any channel
whose capabilities allow the fallback, guarded by a check against
the compile-time generated channel schema metadata. That metadata
only covers core-compiled channels; extension-installed channels
like agentmail have no entry there. The guard treated a missing
schema as "no restriction" and wrote groupAllowFrom anyway, which
agentmail's own runtime schema then rejected, aborting the whole
doctor --fix batch (including unrelated pending migrations).

Fail closed instead: without schema info, don't write the field.

Fixes #116024
2026-07-30 08:43:07 +08:00
Vincent Koc
e473598c2c fix(ui): make model setup actionable before selection (#116079) 2026-07-30 08:34:43 +08:00
Vincent Koc
156d2e623e refactor(channels): own account config mutations (#115970) 2026-07-30 08:20:41 +08:00
Jason (Json)
9991f49ebb fix(discord): keep activity receipts in adopted threads (#116119)
* fix(discord): keep active thread replies together

* fix(discord): preserve adopted thread progress receipts

* test(discord): prove adopted thread reply matching

* fix(discord): preserve receipt on draft finalization failure
2026-07-29 18:08:18 -06:00
metaforismo
3cda5ad32f perf(gateway): cache lazy server methods import (#116060)
* perf(gateway): cache lazy server methods import

* refactor(gateway): use shared lazy runtime loader
2026-07-29 17:07:29 -07:00
Peter Steinberger
a19132e7eb fix(codex): prevent approval promotion from blocking unattended runs (#116117)
* fix(codex): honor hook approval ownership

* fix(codex): keep permission grants human-gated
2026-07-29 17:00:16 -07:00
Ayaan Zaidi
d8074d7ca2 fix(daemon): require system-scope ownership before removing the user unit
Doctor's dueling-scope repair removed the user-scope gateway unit on file
presence alone. A system unit file that is merely staged, disabled, failed, or
uncheckable would then cost the operator their only working gateway, and the
default confirm value is true so non-interactive repair amplifies it.

Gate the removal on isSystemUnitActiveOrEnabled: the system unit must be the
live or boot-configured supervisor. Otherwise doctor explains the ambiguity and
prints both fix directions instead of deleting anything. An erroring probe
fails closed for the same reason.

Applies the ClawSweeper rank-up move on #91221.
2026-07-30 08:52:05 +09:00
北京刻熵科技有限责任公司
dcfd6a535d fix(daemon): only treat same-canonical-name user+system units as dueling
Address review: a marker-owned system unit with a *different* name (e.g. an
intentional rescue-bot gateway on the same host) must not be classified as a
duplicate of the canonical user unit, or doctor could remove a legitimate user
gateway. Dueling now requires user.unitName === system.unitName; the direct
canonical system path still matches the real #79375 case. Adds a regression
test for "user canonical + custom marker-owned system" -> kind:"user".
2026-07-30 08:52:05 +09:00
北京刻熵科技有限责任公司
9308557f72 fix(daemon): detect and resolve dueling user+system systemd gateway units
After upgrading on Linux, a user-scope unit
(~/.config/systemd/user/openclaw-gateway.service) and a system-scope unit
(/etc/systemd/system/openclaw-gateway.service) can both exist and both try to
manage the gateway. They bind the same port and each instance's stale-process
detection SIGTERMs the other, producing an endless restart cascade (#79375).

The detector `findInstalledSystemdGatewayScope` checked the user path first and
returned early, so it could never surface that both scopes coexist.

This adds, in three layers:

1. Detection: `findSystemdGatewayInstallation` — a discriminated union
   (none/user/system/dueling) that reports every installed scope without
   early-returning. `findInstalledSystemdGatewayScope` is refactored to delegate
   to it while preserving the exact user-first preference its four lifecycle
   callers rely on (no behavior change for stop/restart/is-enabled/runtime).
   Adds `uninstallUserSystemdGatewayUnit` (removes only the $HOME user unit, no
   root needed) and the pure `formatDuelingScopesWarning` helper.

2. Doctor: `maybeResolveDuelingSystemdGatewayScopes` detects the dueling state
   and, after the existing confirm/policy gate, removes the redundant user-scope
   unit while keeping the root-installed system unit authoritative. Declining or
   an externally-managed policy falls back to the existing cleanup hints.

3. Startup guard: in service mode, when a stale-kill actually happened, log a
   targeted remediation pointing at `openclaw doctor --fix` instead of letting
   the loop look like routine stale cleanup. Diagnostic only — the kill decision
   is unchanged.
2026-07-30 08:52:05 +09:00
SunnyShu0925
b96ada0680 test: add stalled provider response body timeout coverage 2026-07-30 08:48:52 +09:00
SunnyShu0925
45b34a6dca fix(infra): bound stalled provider JSON/text/error-body reads with default chunk timeout 2026-07-30 08:48:52 +09:00
Vincent Koc
342826b904 test(gateway): cover hook account replay scope (#116121) 2026-07-30 07:23:51 +08:00
Vincent Koc
1f56e2da21 fix(messages): validate configured envelope timezone (#116103)
* fix(messages): validate configured envelope timezone

* fix(messages): preserve UTC envelope rendering

* fix(messages): preserve local fallback mode
2026-07-30 07:18:13 +08:00
Vincent Koc
9e041cd386 fix(hooks): preserve multi-account agent delivery (#116095)
* fix(hooks): preserve account routing for agent delivery

Refs #43866

Co-authored-by: Paul Desmond Parker <paul.parker@dcconnect.cn>

* test(gateway): prove hook account delivery handoff

---------

Co-authored-by: Paul Desmond Parker <paul.parker@dcconnect.cn>
2026-07-30 07:10:21 +08:00
Peter Steinberger
23e151a016 fix(config): reject reserved __proto__ MCP server name (#116112) 2026-07-29 16:09:26 -07:00
Sergio Cadavid
42e21ad13b fix(plugins): keep run context available after registration (#107028) 2026-07-30 07:07:33 +08:00
Vincent Koc
8530edb057 fix(plugins): deliver subagent completion to current requester (#116091)
* fix(plugins): deliver subagent completion to requester

Co-authored-by: ambitioncn <36698505+ambitioncn@users.noreply.github.com>

* test(qa): register current-requester plugin fixture

* fix(plugins): scope requester authority per hook

---------

Co-authored-by: ambitioncn <36698505+ambitioncn@users.noreply.github.com>
2026-07-30 07:06:17 +08:00
Vincent Koc
fc95d7190c fix(hooks): route mapped wake events to configured sessions (#116109)
Fixes #64556
2026-07-30 06:56:19 +08:00
Ayaan Zaidi
daaaef95f0 fix(gateway): cap channels stuck in pending restart
The health monitor lets a pending-restart continuation skip the cooldown so a
timed-out recovery stop can finish on the next pass. That continuation was
never recorded, so an account stuck in restartPending with reconnectAttempts 0
restarted on every check forever, bypassing maxRestartsPerHour entirely: stop
and start thrash the channel manager with log spam and no give-up state.

Only the first continuation per pending episode is now free. Later passes
rejoin cooldown and the hourly budget, and the free pass re-arms only after
the account genuinely leaves restartPending (running again or the pending flag
dropped) so a transient reconnectAttempts bump cannot mint new free restarts.
2026-07-30 07:53:14 +09:00
Peter Steinberger
695391b3ce fix(gateway): evict idle agent terminal sessions under pool pressure (#116101)
* fix(gateway): evict idle agent terminal sessions under pool pressure

* fix(gateway): claim eviction victims and kill only after replacement spawn

* fix(gateway): revalidate eviction victims after the replacement spawn

* fix(gateway): count in-flight reservations when committing eviction

* fix(gateway): reselect eviction victim at commit time

* fix(gateway): release eviction claims on cancelled opens
2026-07-29 15:31:44 -07:00
Vincent Koc
925fdb023e refactor(ui): remove retired time format bootstrap (#116097) 2026-07-29 22:23:27 +00:00
Vincent Koc
43945b836a fix(hooks): retain manual reset memory admission (#116094)
Refs #113396
2026-07-30 06:22:31 +08:00
Vincent Koc
54e273e695 fix(agents): keep date reasoning current in long-running sessions (#116090)
* fix(agents): ground date reasoning below cache boundary

Co-authored-by: Deepak Jain <406777+deepujain@users.noreply.github.com>

* docs: refresh temporal context map

* chore: leave release notes to release curation

* test(agents): keep compaction date mock complete

---------

Co-authored-by: Deepak Jain <406777+deepujain@users.noreply.github.com>
2026-07-29 22:12:47 +00:00
Yuval Dinodia
51241c4e00 fix(agents): edit tool rewrites line endings on lines it did not touch (#116011)
* fix(agents): edit tool rewrites line endings on lines it did not touch

The edit tool detected one line ending from the file's first newline,
normalized the whole file to LF for matching, then re-applied that single
ending to every line on write. A one-line edit therefore rewrote the
terminator of every untouched line, and deleted lone carriage returns
that were data rather than line breaks. The diff and unified patch
returned to the model are computed on the normalized text, so the damage
never surfaces in the tool result or the TUI preview.

Rebuild the written text from the original terminators instead. A bare
carriage return is tracked as its own terminator, so lines the edits did
not touch keep their exact bytes and a rewritten line is written back
with the terminator bytes it had. Newly written lines take the
terminator of the original line they replaced. Matching still runs in LF
space, so LF oldText against a CRLF file matches as before.

* fix(agents): preserve CR fallback for leading edit insertions

* fix(agents): align replacement line-ending boundaries

* fix(agents): preserve edit line-ending provenance

* refactor(agents): isolate edit replacement reconstruction

* test(agents): cover edits through production line endings

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 05:49:56 +08:00
Ayaan Zaidi
c661061d4a fix(agents): keep streamed pre-tool assistant text in claude-cli final output
The claude-cli terminal result envelope carries only the final message text.
On the default draft-preview path (no block streaming, no commentary
classification) the preview streamed every text block, then final delivery
edited it down to just the post-tool closer, silently erasing pre-tool
answer text (#106760).

Both the incremental parser and the transcript reparse now keep the
streamed accumulation when it is connected to the result through tool
splits: boundaries join with a paragraph break, non-tool message
boundaries restart preservation candidacy (superseded drafts still defer
to the envelope), interim results commit their segment without breaking
cumulative delta snapshots, and transcript reparses continue past interim
results like the incremental parser.
2026-07-30 06:48:01 +09:00
Adam Kalsey
e85e1dba3f fix(plugins): keep next-turn injections callable after register (#111131)
Co-authored-by: guptaishaan <guptaishaan@users.noreply.github.com>
2026-07-30 05:47:00 +08:00
Peter Steinberger
8fefe62ba4 fix(agents): settle aborted runs through after-turn so agent_end fires (#116087) 2026-07-29 17:44:51 -04:00
Vincent Koc
215e49b1a2 fix(hooks): report eventless hooks as not ready (#116083)
Fixes #72370

Release note: hooks check now reports selected hooks without declared events as not ready instead of ready.
2026-07-30 05:29:25 +08:00
Peter Steinberger
b9377f6048 fix(codex): enforce native MCP tool access (#116054)
* fix(codex): enforce native MCP tool access

* chore: remove prerelease changelog entry

* chore: restore changelog to main

* refactor(codex): build MCP server patches from entries
2026-07-29 17:06:49 -04:00
Peter Steinberger
7380875375 fix(memory): keep degraded status actionable (#116074)
* fix(memory): diagnose degraded auth owners

* fix(memory): use shared sqlite opener
2026-07-29 16:58:57 -04:00
metaforismo
55dd5d5c93 fix(agents): isolate finalize revision retries (#116006)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:50:23 +08:00
Frank Yang
511ecd9dba fix(plugins): expose inbound message id before dispatch (#112359)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:26:28 +08:00
salvormallow
73b5e7aab4 fix(hooks): save memory on automatic session rollover (#61675)
* fix(hooks): persist memory on session rollover

Co-authored-by: salvormallow <15044561+salvormallow@users.noreply.github.com>

* fix(hooks): persist memory on automatic session reset

* fix(hooks): keep auto-reset reason internal

* fix(hooks): retain auto-reset memory admission

* fix(hooks): make session rollover return explicit

* test(hooks): track session memory temp dirs

* fix(hooks): satisfy session memory return contract

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:13:26 +08:00
Peter Steinberger
d6f9affe79 feat(cli): run agent exec against the ambient config, composed in memory (#116038)
* feat(cli): run agent exec against the ambient config, composed in memory

Exec previously ignored the operator's config entirely, so a one-shot turn
could not reach configured providers, credentials, or agentRuntime harness
selection. It now layers config the way other folder-scoped coding CLIs do.

The composed config is published as this process's runtime snapshot rather
than serialized to a temp file and re-read through OPENCLAW_CONFIG_PATH. The
snapshot is the only in-process config cache, so the file only ever fed it --
while writing env-substituted provider keys to disk where the run's own exec
tool could read them.

* fix(cli): resolve exec stored credentials from the configured agent dir

* chore(scripts): allow agent exec the file-scoped config loader at its process boundary

* test(cli): cover the exec credential default and pinned-config flags
2026-07-29 15:38:27 -04:00
mikasa
d2f2123da5 fix #95351: [Feature]: Generic JSONL line-parsing hook for CliBackendPlugin (native tool-card support beyond claude-stream-json) (#95386)
* feat(plugin-sdk): add CLI backend JSONL parser hook

* fix(test): isolate non-git workspace fixtures

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:37:39 +08:00
Stellar鱼
42e23c11e0 feat(plugins): allow per-turn tool narrowing in prompt hooks (#114151)
* feat(plugins): allow per-turn tool narrowing in prompt hooks

* fix(hooks): keep prompt tool policy baseline internal

* fix(test): track active tools in embedded session fixture

* test(agents): preserve active tool fixture state

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:28:45 +08:00
Kevin Lin
ec32f181a1 fix: Slack replies recover after gateway startup replay (#115991)
* fix: diagnose prepared model owner config drift

* fix(gateway): bind replies to published model owner

* fix(gateway): bind durable replay to published owner

* test: preserve requested workspace in reply mock
2026-07-29 12:25:45 -07:00
Jason (Json)
46ec7a43a8 fix(agents): prevent model runtime startup timeout (#116039) 2026-07-29 13:17:07 -06:00