Commit Graph

73794 Commits

Author SHA1 Message Date
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
Vincent Koc
636d7705c4 fix(feishu): preserve source time in message envelopes (#116156) 2026-07-30 09:27:01 +08:00
Vincent Koc
ffa99ca81d fix(docker): validate timezone in runtime image (#116153) 2026-07-30 09:19:01 +08:00
Peter Steinberger
ec46d30fbf fix(codex): preserve requester across approval bridge (#116152) 2026-07-29 18:16:51 -07: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
d9565bf677 fix(mattermost): honor configured envelope timezone (#116145) 2026-07-30 09:14:40 +08:00
Yuval Dinodia
772235cc55 fix(memory-core): stop MEMORY.md compaction from deleting user headings (#116057)
* fix(memory-core): stop MEMORY.md compaction from deleting user headings

parseMemoryBlocks segmented MEMORY.md only on "## ", so a user heading of
any other level did not close the promotion section above it. The section
ran on to the next "## " heading or EOF, and dropping it to fit the budget
deleted the user text it had swallowed, with no backup and no diagnostic.

Close the current block on any ATX heading, keeping the generator's own
"### Global" and "### Project: <key>" subheadings inside the promotion
body so multi-project sections stay droppable whole.

* fix(memory-core): identify generated promotion subsections by their entry marker

The first exception treated every "### Global" and "### Project: <key>"
heading under a promotion block as dreaming-owned, so a user who wrote one
of those headings themselves still lost it to compaction, which is the same
data-loss class this change set out to fix.

A generated subsection always leads with an openclaw-memory-promotion entry
marker comment, so require that marker as the next non-blank line before
treating the heading as part of the promotion body. User headings that
collide with the generated names now terminate the block and survive.

* fix(memory-core): recognize tab-delimited and empty ATX headings

The heading detector required a literal ASCII space after the opening #
sequence. CommonMark also allows a tab or end of line, so a user note
starting with a tab-delimited heading stayed inside the promotion block
above it and was deleted when compaction dropped that block.

Accept a space, a tab, or end of line after the # sequence. The generated
subsection pattern stays space-only because that is what buildPromotionSection
emits, so a tab-delimited heading is user-authored and is preserved.

* fix(memory-core): preserve Setext headings during compaction

Setext headings were still absorbed into the generated promotion block above them, so dropping that block could silently delete durable user notes. Move the heading paragraph into a preserved block when its underline is encountered, while keeping marker-backed generated content compactable.

* fix(memory-core): preserve indented ATX headings

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 09:13:57 +08:00
QiuYuang
87c71cf0ab fix(voice-call): reject malformed telnyx timestamps (#107565) 2026-07-30 09:12:10 +08:00
Vincent Koc
2d9cf7b6d1 improve(ui): guide optional channel setup after model setup (#116078) 2026-07-30 09:08:07 +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
Brian Snyder
cce8a21492 fix(codex): accept finalizer prompt echoes (#116044)
Co-authored-by: BSnizND <199837910+BsnizND@users.noreply.github.com>
2026-07-30 09:03:01 +08:00
Vincent Koc
1065c1d697 fix(ui): identify source builds in settings footer (#116134)
* fix(ui): identify source builds in settings footer

* fix(release): classify all official Control UI builds
2026-07-30 08:58:34 +08:00
joshavant
545350488a fix(mattermost): preserve outbound delivery settlement 2026-07-29 19:56:34 -05:00
licheer-zte
6288a750ca fix(android): move Wear capability keep rules to raw keep files to prevent resource shrinking (#116068)
* fix(android): move Wear capability keep rules to raw keep files

Resource-shrinker keep directives in res/values/*.xml are not honored
by Android's resource shrinker during release builds. Move the
tools:keep declarations into dedicated res/raw/*.keep.xml files as
documented by Android:
https://developer.android.com/topic/performance/app-optimization/customize-which-resources-to-keep

Fixes openclaw/openclaw#116049

* fix(android): rename keep files - use underscores instead of dots

Android resource names must contain only lowercase a-z, 0-9, and underscores.
Dots in file names cause build failure with AAPT2 resource merger.

- ai.openclaw.app.phone.keep.xml -> ai_openclaw_app_phone_keep.xml
- ai.openclaw.app.wear.keep.xml -> ai_openclaw_app_wear_keep.xml

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 08:55:45 +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
Peter Steinberger
1165be39ff ci: serialize hosted macOS Swift tests (#116137) 2026-07-29 17:40:41 -07: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
c868c81e91 fix(feishu): preserve card actions through mention gating (#116105)
* fix(feishu): preserve card actions through mention gating

* test(feishu): use structured card action fixtures
2026-07-29 17:07:42 -07: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
Shakker
68c472f379 refactor: keep update timing constants private 2026-07-30 01:03:51 +01:00
Shakker
899573a8c6 fix: reject stale update reconciliation 2026-07-30 01:03:51 +01:00
Shakker
e2654017d4 refactor: keep update status response private 2026-07-30 01:03:51 +01:00
Shakker
302e394455 fix: bound update status reconciliation 2026-07-30 01:03:51 +01:00
Shakker
f8aa44dcda fix: preserve uncertain update outcomes 2026-07-30 01:03:51 +01:00
Shakker
8d47c7d274 refactor: keep update reconciliation within size budgets 2026-07-30 01:03:51 +01:00
Shakker
ce8995f716 fix: release update reconciliation on access loss 2026-07-30 01:03:51 +01:00
Shakker
55b4c8c65d docs: note control ui update reconciliation 2026-07-30 01:03:51 +01:00
Shakker
1408dad5d5 test: cover both managed update response orders 2026-07-30 01:03:51 +01:00
Shakker
a69fea5f2d fix: reconcile ambiguous gateway updates 2026-07-30 01:03:51 +01: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
Vincent Koc
514ab48d17 fix(macos): back off approval socket retries (#116125) 2026-07-30 07:52:01 +08: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
Ayaan Zaidi
73ab157e6f docs(agents): calibrate defaults ambition and security tradeoff in Product Doctrine 2026-07-30 08:44:40 +09:00
Peter Steinberger
d60436a4ee feat(ui): transcode renditions and waveform audio cards (#116115)
* feat(ui): add chat media renditions and waveforms

* fix(ui): tighten media playback guards

* fix(ui): bound waveform decode memory

* fix(ui): harden media playback retries

* fix(ui): preserve valid media state

* fix(ui): stop detached video playback

* fix(ui): bound media artifact resolution

* fix(ui): reject failed media fallback sources

* refactor(ui): split attachment availability helpers

* fix(ui): unload media across auth resets

* fix(ui): retain the longest-lived media ticket
2026-07-29 16:44:05 -07:00
yetval
cdab176484 fix(memory-wiki): isolate bridge pages for sandboxed callers
Sandboxed sub-agents could read another agent's bridge-compiled memory through the shared global vault via wiki_get, wiki_search, and the memory_get/memory_search corpus fallback. The wiki-corpus read path now filters pages through one visibility gate that fails closed for bridge-compiled pages a sandboxed caller does not own, including bridge pages that carry no ownership metadata.
2026-07-30 08:32:41 +09:00
Vincent Koc
342826b904 test(gateway): cover hook account replay scope (#116121) 2026-07-30 07:23:51 +08:00
Vincent Koc
de67565cda fix(macos): back off failed Gateway connects (#116114)
* fix(macos): back off failed gateway connects

* fix(macos): skip backoff for transport cancellation
2026-07-30 07:23:22 +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